{"id":27172,"date":"2018-01-03T22:02:44","date_gmt":"2018-01-03T16:32:44","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=27172"},"modified":"2018-10-29T13:07:32","modified_gmt":"2018-10-29T07:37:32","slug":"java-programming-maximum-sum-rectangle-in-a-2d-matrix","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/java-programming-maximum-sum-rectangle-in-a-2d-matrix\/","title":{"rendered":"Maximum sum rectangle in a 2D matrix"},"content":{"rendered":"<p>Given a <a href=\"https:\/\/www.wikitechy.com\/tutorials\/javascript\/create-a-two-dimensional-array-in-javascript\" target=\"_blank\" rel=\"noopener\">2D array<\/a>, find the maximum sum subarray in it. For example, in the following 2D array, the maximum sum subarray is highlighted with blue rectangle and sum of this subarray is 29.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"size-full wp-image-27173 aligncenter\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Maximum-sum-rectangle-in-a-2D-matrix.png\" alt=\"Maximum sum rectangle in a 2D matrix\" width=\"293\" height=\"247\" \/><\/p>\n<p>This problem is mainly an extension of <strong>Largest Sum Contiguous Subarray<\/strong> for 1D array.<\/p>\n<p>The <strong>naive solution<\/strong> for this problem is to check every possible rectangle in given 2D array. This solution requires 4 <a href=\"https:\/\/www.wikitechy.com\/tutorials\/java\/the-if-else-if-statement-nested-if-statements-logical-operators-in-java\" target=\"_blank\" rel=\"noopener\">nested loops<\/a> and time complexity of this solution would be <strong>O(n^4).<\/strong><\/p>\n[ad type=&#8221;banner&#8221;]\n<h3 id=\"kadanes-algorithm\"><span style=\"color: #800000;\"><strong>Kadane\u2019s algorithm:<\/strong><\/span><\/h3>\n<p><strong>Kadane\u2019s algorithm<\/strong> for 1D array can be used to reduce the time complexity to<strong> O(n^3)<\/strong>. The idea is to fix the left and right columns one by one and find the maximum sum contiguous rows for every left and right column pair. We basically find top and bottom row numbers (which have maximum sum) for every fixed left and right column pair.<\/p>\n<p>To find the top and bottom row numbers, calculate sum of elements in every row from left to right and store these sums in an <a href=\"https:\/\/www.wikitechy.com\/technology\/c-programming-check-array-can-divided-pairs-whose-sum-divisible-k\/\" target=\"_blank\" rel=\"noopener\">array<\/a> say temp[]. So temp[i] indicates sum of elements from left to right in row i. If we apply Kadane\u2019s 1D algorithm on temp[], and get the maximum sum subarray of temp, this maximum sum would be the maximum possible sum with left and right as boundary columns. To get the overall maximum sum, we compare this sum with the maximum sum so far.<\/p>\n<p>&nbsp;<\/p>\n<h3 id=\"java-implementation-for-maximum-sum-rectangle-in-a-2d-matrix\"><span style=\"color: #008080;\">Java implementation for\u00a0Maximum sum rectangle in a 2D matrix:<\/span><\/h3>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">Java<\/span> <\/div> <pre class=\"language-java code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-java code-embed-code\">import java.util.*;<br\/>import java.lang.*;<br\/>import java.io.*;<br\/> <br\/><br\/>class Ideone<br\/>{<br\/>    public static void main (String[] args) throws java.lang.Exception<br\/>    {<br\/>        findMaxSubMatrix(new int[][] {<br\/>                            {1, 2, -1, -4, -20},<br\/>                            {-8, -3, 4, 2, 1},<br\/>                            {3, 8, 10, 1, 3},<br\/>                            {-4, -1, 1, 7, -6}<br\/>                            });<br\/>    }<br\/> <br\/>    public static int[] kadane(int[] a) {<br\/>              int[] result = new int[]{Integer.MIN_VALUE, 0, -1};<br\/>        int currentSum = 0;<br\/>        int localStart = 0;<br\/>     <br\/>        for (int i = 0; i &lt; a.length; i++) {<br\/>            currentSum += a[i];<br\/>            if (currentSum &lt; 0) {<br\/>                currentSum = 0;<br\/>                localStart = i + 1;<br\/>            } else if (currentSum &gt; result[0]) {<br\/>                result[0] = currentSum;<br\/>                result[1] = localStart;<br\/>                result[2] = i;<br\/>            }<br\/>        }<br\/>         <br\/>        <br\/>        if (result[2] == -1) {<br\/>            result[0] = 0;<br\/>            for (int i = 0; i &lt; a.length; i++) {<br\/>                if (a[i] &gt; result[0]) {<br\/>                    result[0] = a[i];<br\/>                    result[1] = i;<br\/>                    result[2] = i;<br\/>                }<br\/>            }<br\/>        }<br\/>         <br\/>        return result;<br\/>    }<br\/> <br\/>    <br\/>    public static void findMaxSubMatrix(int[][] a) {<br\/>        int cols = a[0].length;<br\/>        int rows = a.length;<br\/>        int[] currentResult;<br\/>        int maxSum = Integer.MIN_VALUE;<br\/>        int left = 0;<br\/>        int top = 0;<br\/>        int right = 0;<br\/>        int bottom = 0;<br\/>         <br\/>        for (int leftCol = 0; leftCol &lt; cols; leftCol++) {<br\/>            int[] tmp = new int[rows];<br\/>     <br\/>            for (int rightCol = leftCol; rightCol &lt; cols; rightCol++) {<br\/>         <br\/>                for (int i = 0; i &lt; rows; i++) {<br\/>                    tmp[i] += a[i][rightCol];<br\/>                }<br\/>                currentResult = kadane(tmp);<br\/>                if (currentResult[0] &gt; maxSum) {<br\/>                    maxSum = currentResult[0];<br\/>                    left = leftCol;<br\/>                    top = currentResult[1];<br\/>                    right = rightCol;<br\/>                    bottom = currentResult[2];<br\/>                }<br\/>            }<br\/>        }<br\/>              System.out.println(&quot;MaxSum: &quot; + maxSum + <br\/>                               &quot;, range: [(&quot; + left + &quot;, &quot; + top + <br\/>                                 &quot;)(&quot; + right + &quot;, &quot; + bottom + &quot;)]&quot;);<br\/>    }<br\/>}<\/code><\/pre> <\/div>\n<h3 id=\"output\"><span style=\"color: #008000;\"><strong>Output :<\/strong><\/span><\/h3>\n<pre>Max sum is: 29, range: [(1,1)(3,3]<\/pre>\n<p><strong><span style=\"color: #0000ff;\">Time Complexity:<\/span> O(n^3)<\/strong><\/p>\n[ad type=&#8221;banner&#8221;]\n<div class=\"responsive-tabs-wrapper\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Java Programming &#8211; Maximum sum rectangle in a 2D matrix &#8211; Dynamic Programming &#8211; Given a 2D array, find the maximum sum subarray in it. For example<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,70145,2139],"tags":[78231,79936,79156,79929,80989,79938,80990,80993,80987,72855],"class_list":["post-27172","post","type-post","status-publish","format-standard","hentry","category-coding","category-dynamic-programming","category-java","tag-kadanes-algorithm-java","tag-maximum-product-subarray","tag-maximum-size-square-sub-matrix-with-all-1s","tag-maximum-subarray","tag-maximum-subarray-of-size-hxw-within-a-2d-matrix","tag-maximum-subarray-sum","tag-maximum-submatrix-with-all-1s","tag-maximum-sum-rectangle-in-a-2d-matrix-c-code","tag-maximum-sum-rectangular-submatrix-in-matrix-dynamic","tag-simple-dynamic-programming-example"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=27172"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27172\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=27172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=27172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=27172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}