/// <summary> /// Here given an array we find the maximum sum in the 1_D array /// This can be done using the Kadane Algorithm /// </summary> /// <param name="arr"></param> /// <returns>KadaneResult object</returns> public KadaneResult GetMaxInArray(int[] arr) { KadaneResult result = new KadaneResult(0, 0, arr[0]); int currentSum = (arr[0] >= 0) ? arr[0] : 0; int currentStart = (arr[0] >= 0) ? 0 : 1; for (int i = 1; i < arr.Length; i++) { currentSum += arr[i]; if (currentSum > result.MaximumSum) { // Here we have found a 1-D array which has the maxSum result.StartIndex = currentStart; result.EndIndex = i; result.MaximumSum = currentSum; } if (currentSum < 0) { // if the currentSum is negative we need to reset the startIndex and the currentSum currentSum = 0; currentStart = i + 1; } } return(result); }
public static KadaneResult kadane(int[] arr) { int max_Sum = arr[0]; int curr_Sum = arr[0]; int curr_Top = 0; int top = 0; int bottom = 0; for (int i = 1; i < arr.Length; i++) { if (curr_Sum >= 0) { curr_Sum += arr[i]; } else { curr_Sum = arr[i]; curr_Top = i; } if (max_Sum < curr_Sum) { max_Sum = curr_Sum; top = curr_Top; bottom = i; } } KadaneResult kd = new KadaneResult(top, bottom, max_Sum); return(kd); }
/// <summary> /// We can use dynamic programming to get the maximum sum in a 2-D matrix. /// Keep getting the cummulative sum of rectangles with different left and right index /// And do Kadanes 1D max sum algorithm to get the top and bottom index. /// /// The total running time of this algorithm is O(row*col*col) /// And the space requirement is O(row) /// </summary> /// <param name="mat"></param> /// <returns></returns> public Rectangle GetMaxRectangleInMatrix(int[,] mat) { Rectangle rect = new Rectangle(0, 0, 0, 0, int.MinValue); int[] cummulativeSum = new int[mat.GetLength(0)]; for (int currentLeft = 0; currentLeft < mat.GetLength(1); currentLeft++) { //Make all elements in cummulativeSum =0 for (int i = 0; i < cummulativeSum.Length; i++) { cummulativeSum[i] = 0; } for (int currentRight = currentLeft; currentRight < mat.GetLength(1); currentRight++) { for (int i = 0; i < mat.GetLength(0); i++) { cummulativeSum[i] += mat[i, currentRight]; } KadaneResult result = GetMaxInArray(cummulativeSum); if (result.MaximumSum > rect.MaxSum) { // We have a new maximum rect.MaxSum = result.MaximumSum; rect.LeftIndex = currentLeft; rect.RightIndex = currentRight; rect.TopIndex = result.StartIndex; rect.BottomIndex = result.EndIndex; } } } return(rect); }
public static Result maxSumRectangle(int[,] arr) { int row = arr.GetLength(0); int col = arr.GetLength(1); Result res = new Result(); for (int left = 0; left < col; left++) { int[] temp = new int[row]; for (int right = left; right < col; right++) { for (int i = 0; i < row; i++) { temp[i] += arr[i, right]; } KadaneResult kd = kadane(temp); if (res.maxSum < kd.maxSum) { res.maxSum = kd.maxSum; res.top = kd.top; res.bottom = kd.bottom; res.left = left; res.right = right; } } } return(res); }