forked from rampatra/Algorithms-and-Data-Structures-in-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaximumSubArray.java
104 lines (86 loc) · 3.16 KB
/
MaximumSubArray.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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: <a href="https://leetcode.com/submissions/detail/225130466/">0 ms</a>.
*
* @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: <a href="https://leetcode.com/submissions/detail/225140123/">1 ms</a>.
*
* @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}));
}
}