package com.anuragkapur.misc; /** * A divide and conquer paradigm based algorithm * * @author anurag.kapur */ public class MaxSubarrayProblem { static int numbers[] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4 }; //static int numbers[] = {13, 3, 25, 20, -3, -16, -23, -18, -20, -7, -12,-5, -22, 15, -4}; // static int numbers[] = {13, -33, 25, 20}; public static String maxSubarrayCrossingMid(int startIndex, int endIndex, int mid) { int runningSum = numbers[mid]; int maxLeftSum = runningSum; int leftIndex = mid; int rightIndex = mid + 1; // Travel left from mid for (int i = mid - 1; i >= startIndex; i--) { runningSum += numbers[i]; if (runningSum >= maxLeftSum) { maxLeftSum = runningSum; leftIndex = i; } } // Travel right from mid runningSum = numbers[mid + 1]; int maxRightSum = runningSum; for (int i = mid + 2; i <= endIndex; i++) { runningSum += numbers[i]; if (runningSum >= maxRightSum) { maxRightSum = runningSum; rightIndex = i; } } if (maxRightSum >= 0) { String subArrayData = leftIndex + "," + rightIndex; int sum = maxLeftSum + maxRightSum; return sum + "," + subArrayData; } else { String subArrayData = leftIndex + "," + mid; return maxLeftSum + "," + subArrayData; } } public static String maxSubarray(int startIndex, int endIndex) { System.out.println("startIndex :: " + startIndex + " endIndex :: " + endIndex); if (endIndex == startIndex || endIndex < startIndex) { // Recursion base case 2 return numbers[startIndex] + "," + startIndex + "," + endIndex; } else { // Recursive case int mid = (endIndex + startIndex) / 2; // find max subarray recursively in sub problems String leftSubArrayData = maxSubarray(startIndex, mid - 1); int sumLeft = Integer.parseInt(leftSubArrayData.substring(0,leftSubArrayData.indexOf(","))); String rightSubArrayData = maxSubarray(mid + 1, endIndex); int sumRight = Integer.parseInt(rightSubArrayData.substring(0,rightSubArrayData.indexOf(","))); // find max subarray where subarray contains the mid element (this // is like the combine step of the divide and conquer paradigm) String midSubArrayData = maxSubarrayCrossingMid(startIndex, endIndex, mid); int sumMiddle = Integer.parseInt(midSubArrayData.substring(0, midSubArrayData.indexOf(","))); // find which sum is max and return it if (sumLeft > sumRight && sumLeft > sumMiddle) { return leftSubArrayData; } else if (sumRight > sumLeft && sumRight > sumMiddle) { return rightSubArrayData; } else { return midSubArrayData; } } } /** * @param args */ public static void main(String[] args) { System.out.println(maxSubarray(0, 14)); } }