package com.leetcode.arrays; /** * Level: Easy * Problem Link: https://leetcode.com/problems/maximum-subarray * * @author rampatra * @since 2019-04-26 */ public class MaximumSubArray { /** * Time complexity: O(n) * Runtime: 0 ms. * * @param nums * @return */ public static int maxSubArray(int[] nums) { if (nums.length == 0) { return 0; } int consecutiveSum = nums[0]; int maxSum = nums[0]; for (int i = 1; i < nums.length; i++) { consecutiveSum += nums[i]; /* if the current number is larger than the summation of all the previous numbers then start from current number */ if (nums[i] > consecutiveSum) { consecutiveSum = nums[i]; } if (consecutiveSum > maxSum) { maxSum = consecutiveSum; } } return maxSum; } /** * Divide and Conquer approach. * Time complexity: O(n log n). See Master's Theorem to understand how. * Runtime: 1 ms. * * @param nums * @return */ public static int maxSubArrayDivideAndConquer(int[] nums) { return maxSubArrayDivideAndConquer(nums, 0, nums.length - 1); } public static int maxSubArrayDivideAndConquer(int[] nums, int start, int end) { if (start == end) { return nums[start]; } int mid = start + (end - start) / 2; int leftSASum = maxSubArrayDivideAndConquer(nums, start, mid); int rightSASum = maxSubArrayDivideAndConquer(nums, mid + 1, end); int leftSum = Integer.MIN_VALUE; int rightSum = Integer.MIN_VALUE; // compute consecutive sum from mid towards start int sum = 0; for (int i = mid; i >= start; i--) { sum += nums[i]; if (sum > leftSum) { leftSum = sum; } } // compute consecutive sum from mid towards end sum = 0; for (int i = mid + 1; i <= end; i++) { sum += nums[i]; if (sum > rightSum) { rightSum = sum; } } // return the max of left sub-array, right sub-array, and the consecutive sum between start and end via mid return Math.max(Math.max(leftSASum, rightSASum), leftSum + rightSum); } public static void main(String[] args) { System.out.println(maxSubArray(new int[]{3})); System.out.println(maxSubArray(new int[]{-3})); System.out.println(maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); System.out.println(maxSubArray(new int[]{4, -5, 1, 2, -1, 4, -3, 1, -2})); System.out.println("----"); System.out.println(maxSubArrayDivideAndConquer(new int[]{3})); System.out.println(maxSubArrayDivideAndConquer(new int[]{-3})); System.out.println(maxSubArrayDivideAndConquer(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); System.out.println(maxSubArrayDivideAndConquer(new int[]{4, -5, 1, 2, -1, 4, -3, 1, -2})); } }