Example #1
0
        // 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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        // 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);
        }