public MaxSubarrayResult FindMaxSubarray(int[] values, int startIndex, int endIndex) { // Divide and Conquer algorithm - O(n * log[n]) var result = new MaxSubarrayResult(); if (startIndex == endIndex) { result.StartIndex = startIndex; result.EndIndex = endIndex; result.Value = values[startIndex]; return(result); } int midIndex = (startIndex + endIndex) / 2; var leftResult = FindMaxSubarray(values, startIndex, midIndex); var rightResult = FindMaxSubarray(values, midIndex + 1, endIndex); var midResult = FindMaxThroughMid(values, startIndex, midIndex, endIndex); if (leftResult.Value >= midResult.Value && leftResult.Value >= rightResult.Value) { return(leftResult); } if (rightResult.Value >= leftResult.Value && rightResult.Value >= midResult.Value) { return(rightResult); } return(midResult); }
public override MaxSubarrayResult FindMaxSubarray(int[] values) { // Fast algorithm by Kadane - O(n) // // Discussed briefly in Section 4.1-5 of Introduction to Algorithms, the reader // is encouraged to develop a non-recursive solution. This algorithm is also known // as Kadane's algorithm. // // More information: https://en.wikipedia.org/wiki/Maximum_subarray_problem // // My algorithm here is just slightly enhanced to track the start and end index, as // well as the actual value. // // This is a simple form of dynamic programming - results of solving subproblems // are passed up the solution chain. var result = new MaxSubarrayResult() { StartIndex = -1, EndIndex = -1, Value = Int32.MinValue }; if (values.Length == 0) { return(result); } result.StartIndex = 0; result.EndIndex = 0; result.Value = values[0]; int currStartIndex = 0; int currEndIndex = 0; int currMax = values[0]; for (int endIndex = 1; endIndex < values.Length; endIndex++) { if (currMax + values[endIndex] > values[endIndex]) { currMax += values[endIndex]; currEndIndex = endIndex; } else { currStartIndex = endIndex; currEndIndex = endIndex; currMax = values[endIndex]; } if (currMax > result.Value) { result.StartIndex = currStartIndex; result.EndIndex = currEndIndex; result.Value = currMax; } } return(result); }
public override MaxSubarrayResult FindMaxSubarray(int[] values) { // A slow, O(n^2) algorithm var result = new MaxSubarrayResult() { Value = Int32.MinValue }; for (int startIndex = 0; startIndex < values.Length; startIndex++) { int sum = 0; for (int endIndex = startIndex; endIndex < values.Length; endIndex++) { sum += values[endIndex]; if (sum > result.Value) { result.StartIndex = startIndex; result.EndIndex = endIndex; result.Value = sum; } } } return(result); }
static void PrintResult(string method, MaxSubarrayResult result) { string heading = "Max Subarray Result, Method = "; Console.WriteLine("{0}{1}", heading, method); Console.WriteLine(new String('-', heading.Length + method.Length)); Console.WriteLine("Start Index: {0}", result.StartIndex); Console.WriteLine("End Index : {0}", result.EndIndex); Console.WriteLine("Value : {0}", result.Value); Console.WriteLine(); }
public MaxSubarrayResult FindMaxThroughMid(int[] values, int startIndex, int midIndex, int endIndex) { var result = new MaxSubarrayResult() { StartIndex = -1, EndIndex = -1, Value = Int32.MinValue }; int maxLeft = Int32.MinValue; int leftSum = 0; for (int index = midIndex; index >= startIndex; index--) { leftSum += values[index]; if (leftSum > maxLeft) { result.StartIndex = index; maxLeft = leftSum; } } int maxRight = Int32.MinValue; int rightSum = 0; for (int index = midIndex + 1; index <= endIndex; index++) { rightSum += values[index]; if (rightSum > maxRight) { result.EndIndex = index; maxRight = rightSum; } } result.Value = maxLeft + maxRight; return(result); }