{"id":327,"date":"2020-12-26T23:48:08","date_gmt":"2020-12-26T23:48:08","guid":{"rendered":"https:\/\/www.canosielabs.com\/blog\/?p=327"},"modified":"2020-12-26T23:48:10","modified_gmt":"2020-12-26T23:48:10","slug":"maximum-subarray","status":"publish","type":"post","link":"https:\/\/www.canosielabs.com\/blog\/maximum-subarray\/","title":{"rendered":"Maximum Subarray"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Today we take a look at <a href=\"https:\/\/leetcode.com\/explore\/item\/566\">Maximum Subarray<\/a>  Though problem is a common problem asked during interviews and has a straight forward answer, many struggle on the what the dynamic programming table should keep track of -so it&#8217;s worth doing a deeper study of the problem.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The intuition behind the solution relies on three facts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Fact 1:<\/strong>  We don&#8217;t need to keep track of the actual subarray that will give us the maximum sub, we just need to know the max sum.  This is <strong>important<\/strong>.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Fact 2:<\/strong> If the input contained all positive numbers, the max subarray would be the entire array.  Negative values in the array cause the subarray to be less than the full input. <strong>This is important to the intuition behind the solution.<\/strong>  As we traverse the array, at each position, <strong><code>i<\/code><\/strong>, we want to see if we should include it in the previous subarray or create a new subarray starting at <strong>i<\/strong>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Fact 3:<\/strong> Continuing from <strong>fact 2<\/strong>, given such a number<code><strong> nums[i+1]<\/strong><\/code>, we can decide if it should be included in the existing subarray or become the start of a new subarray by seeing <strong><code>sum(<code>[nums[j], nums[j+1], ... nums[i], nums[i+1]]<\/code>)<\/code> <\/strong>is less than <code><strong>nums[i+1]<\/strong>.<\/code>   If <strong><code>nums[i+1] <\/code><\/strong>is grater than the sums, it means that existing subarray carries a negative value <strong>or<\/strong> both the sum and <strong><code>nums[i+1]<\/code><\/strong> are negative.  In either case, it makes sense to start a new subarray starting at index i+1 since <strong>including it in the previous subarray would yield a lower sum value.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And this gives us the intuition behind the solution.  Start at index 0 and traverse though the array keeping track of a running total for each <strong>nums[i]<\/strong> in a separate array.   Let&#8217;s call this separate array <strong><code>memo<\/code><\/strong>. If at some point we see a <strong><code>nums[i]<\/code><\/strong> such that: <strong><code>nums[i] &gt; sum[num[j]..num[i-1], nums[i]) <\/code><\/strong>then, we set <strong><code>memo[i]<\/code><\/strong> to<strong><code> nums[i] <\/code><\/strong>and keep going.   It&#8217;s important to note that <strong><code>memo[n]<\/code><\/strong> does does not mean the actual subarray is <code><strong>nums[0] to nums[n]<\/strong><\/code>.  The actual subarray may be any subset from<code><strong> nums[0] to nums[n]<\/strong><\/code>, such as 4 to n or even just <strong><code>nums[n]<\/code><\/strong> itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After we have traversed though the entire input, we simply iterate though the memo array and return the maximum value found.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><strong>Optimal Substructure<\/strong><\/strong> &#8211; This exists because if we find the optimal solution for inputs <strong><code>nums[0...n],<\/code><\/strong> we can use it&#8217;s solution to find the optimal solution for inputs <strong><code>nums[0..., n, n+1]<\/code><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Overlapping Sub-problem<\/strong> &#8211; This exists because we need to calculate largest sum of any contiguous subarray for each number in the input.  For each number, n, as we carry out the calculation, we require the solution for the subproblem on index n-1 (and so on).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Base case<\/strong> &#8211; By definition, our base case is <code>memo[0] = nums[0]<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">DP Table<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Our solution relies on the &#8220;<strong>memo<\/strong>&#8221; array described in fact 3.  At any position n, this array contains the largest sum of any contiguous subarray\u00a0(either ending at n or just n itself) from in <strong>nums[0&#8230;n]<\/strong>. <\/p>\n\n\n\n<pre><code class=\"language-java\">    public int maxSubArray(int[] nums) {\n     \n        int[] memo = new int[nums.length];\n        memo[0] = nums[0];\n        \n        int maxFound = memo[0];        \n        \n        if (nums == null) {\n            return 0;\n        } else if (nums.length == 1){\n            return nums[0];      \n        }\n\n        for(int i=1;i&lt;nums.length; i++){\n            \n            int currentNum = nums[i];        \n            memo[i] = Math.max(currentNum, memo[i-1]+currentNum);\n            maxFound = maxFound &lt; memo[i] ? memo[i] : maxFound;\n        }\n        \n        return maxFound;\n    }<\/code><\/pre><br><br>\n","protected":false},"excerpt":{"rendered":"<p>Today we take a look at Maximum Subarray Though problem is a common problem asked during interviews and has a straight forward answer, many struggle&hellip;<\/p>\n","protected":false},"author":3,"featured_media":255,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bgseo_title":"","bgseo_description":"","bgseo_robots_index":"index","bgseo_robots_follow":"follow","footnotes":""},"categories":[11],"tags":[10],"class_list":["post-327","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interview-coding-questions","tag-coding-questions"],"_links":{"self":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/comments?post=327"}],"version-history":[{"count":9,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/327\/revisions"}],"predecessor-version":[{"id":336,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/posts\/327\/revisions\/336"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/media\/255"}],"wp:attachment":[{"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/media?parent=327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/categories?post=327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.canosielabs.com\/blog\/wp-json\/wp\/v2\/tags?post=327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}