// Given an NxN matrix of positive and negative integers, write code to find the sub-matrix with the largest possible sum public static MaxSum FindMaxSumSubarray(int[] inArr) { int currMax = 0; int currStartIndex = 0; // initialize maxSum to -infinity, maxStart and maxEnd idx to 0. MaxSum mx = new MaxSum(int.MinValue, 0, 0); // travers through the array for (int currEndIndex = 0; currEndIndex < inArr.Length; currEndIndex++) { // add element value to the current max. currMax += inArr[currEndIndex]; // if current max is more that the last maxSum calculated, set the maxSum and its idx if (currMax > mx.maxSum) { mx.maxSum = currMax; mx.maxStartIdx = currStartIndex; mx.maxEndIdx = currEndIndex; } if (currMax < 0) // if currMax is -ve, change it back to 0 { currMax = 0; currStartIndex = currEndIndex + 1; } } return(mx); }
public static MaxSumMatrix FindMaxSumSubmatrix(int[,] inMtrx) { MaxSumMatrix maxSumMtrx = new MaxSumMatrix(); // Step 1. Create SumMatrix - do the cumulative columnar summation // S[i,j] = S[i-1,j]+ inMtrx[i-1,j]; int m = inMtrx.GetUpperBound(0) + 2; int n = inMtrx.GetUpperBound(1) + 1; int[,] sumMatrix = new int[m, n]; for (int i = 1; i < m; i++) { for (int j = 0; j < n; j++) { sumMatrix[i, j] = sumMatrix[i - 1, j] + inMtrx[i - 1, j]; } } PrintMatrix(sumMatrix); // Step 2. Create rowSpans starting each rowIdx. For these row spans, create a 1-D array r_ij for (int x = 0; x < n; x++) { for (int y = x; y < n; y++) { int[] r_ij = new int[n]; for (int k = 0; k < n; k++) { r_ij[k] = sumMatrix[y + 1, k] - sumMatrix[x, k]; } // Step 3. Find MaxSubarray of this r_ij. If the sum is greater than the last recorded sum => // capture Sum, colStartIdx, ColEndIdx. // capture current x as rowTopIdx, y as rowBottomIdx. MaxSum currMaxSum = KadanesAlgo.FindMaxSumSubarray(r_ij); if (currMaxSum.maxSum > maxSumMtrx.sum) { maxSumMtrx.sum = currMaxSum.maxSum; maxSumMtrx.colStart = currMaxSum.maxStartIdx; maxSumMtrx.colEnd = currMaxSum.maxEndIdx; maxSumMtrx.rowStart = x; maxSumMtrx.rowEnd = y; } } } return(maxSumMtrx); }
static void TestKadanesAlgo() { int[] arr = new int[] { 2, -1, 2, -1, 4, -5 };//{ 7, 3, -4, 8, -9, 1, 5}; MaxSum mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { 4, 7, 4, -2, 8, -10 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { 6, 6, 6, -3, 12, -15 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { 8, 5, 8, -4, 16, -20 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { 10, 4, 10, -5, 20, -25 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { 8, 3, 8, -6, 24, -30 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); // ----------- arr = new int[] { 7, 3, -14, 8, -9, 1, 5 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { -7, -3, -14, -8, -9, -1, -5 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { -7, -3, -14, -8, -9, -1, 0 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); arr = new int[] { -7, 12, 3, 4, 8, -9, -1, -5, 11, 9 }; mx = KadanesAlgo.FindMaxSumSubarray(arr); Console.WriteLine("maxSum = {0}, startIdx = {1}, endIdx = {2}", mx.maxSum, mx.maxStartIdx, mx.maxEndIdx); }
// NOT WORKING public static MaxSum FindMaxLengthSubarrayWithSumX(int[] inArr, int requiredSum) { int currMax = 0; int currStartIndex = 0; // initialize maxSum to -infinity, maxStart and maxEnd idx to 0. MaxSum mx = new MaxSum(int.MinValue, 0, 0); MaxSum xctSum = new MaxSum(requiredSum, -1, -1); // travers through the array for (int currEndIndex = 0; currEndIndex < inArr.Length; currEndIndex++) { // add element value to the current max. currMax += inArr[currEndIndex]; // if current max is more that the last maxSum calculated, set the maxSum and its idx if (currMax > mx.maxSum) { mx.maxSum = currMax; mx.maxStartIdx = currStartIndex; mx.maxEndIdx = currEndIndex; } if (currMax == xctSum.maxSum && (currEndIndex - currStartIndex) > (xctSum.maxEndIdx - xctSum.maxStartIdx)) { xctSum.maxStartIdx = currStartIndex; xctSum.maxEndIdx = currEndIndex; mx = new MaxSum(int.MinValue, 0, 0); currMax = 0; currStartIndex = currEndIndex + 1; } //if (currMax < 0) // if currMax is -ve, change it back to 0 //{ // currMax = 0; // currStartIndex = currEndIndex + 1; //} } return(xctSum); }