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);
        }
Exemple #2
0
        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);
        }