functionLSS(list) { const len = list.length; let max = -Number.MAX_VALUE; let sum = 0; for (let i = 0; i < len; i++) { sum = 0; for (let j = i; j < len; j++) { sum += list[j]; if (sum > max) { max = sum; } } }
return max; }
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classMaximumSubarrayPrefixSum{ publicintmaxSubArray(int[] nums){ int len = nums.length; int maxSum = Integer.MIN_VALUE; int sum = 0; for (int i = 0; i < len; i++) { sum = 0; for (int j = i; j < len; j++) { sum += nums[j]; maxSum = Math.max(maxSum, sum); } } return maxSum; } }
Python 3:
1 2 3 4 5 6 7 8 9 10 11 12 13
import sys classSolution: defmaxSubArray(self, nums: List[int]) -> int: n = len(nums) maxSum = -sys.maxsize sum = 0 for i in range(n): sum = 0 for j in range(i, n): sum += nums[j] maxSum = max(maxSum, sum)
functionhelper(list, m, n) { if (m === n) return list[m]; let sum = 0; let lmax = -Number.MAX_VALUE; let rmax = -Number.MAX_VALUE; const mid = ((n - m) >> 1) + m; const l = helper(list, m, mid); const r = helper(list, mid + 1, n); for (let i = mid; i >= m; i--) { sum += list[i]; if (sum > lmax) lmax = sum; }
sum = 0;
for (let i = mid + 1; i <= n; i++) { sum += list[i]; if (sum > rmax) rmax = sum; }
classMaximumSubarrayDivideConquer{ publicintmaxSubArrayDividConquer(int[] nums){ if (nums == null || nums.length == 0) return0; return helper(nums, 0, nums.length - 1); } privateinthelper(int[] nums, int l, int r){ if (l > r) return Integer.MIN_VALUE; int mid = (l + r) >>> 1; int left = helper(nums, l, mid - 1); int right = helper(nums, mid + 1, r); int leftMaxSum = 0; int sum = 0; // left surfix maxSum start from index mid - 1 to l for (int i = mid - 1; i >= l; i--) { sum += nums[i]; leftMaxSum = Math.max(leftMaxSum, sum); } int rightMaxSum = 0; sum = 0; // right prefix maxSum start from index mid + 1 to r for (int i = mid + 1; i <= r; i++) { sum += nums[i]; rightMaxSum = Math.max(sum, rightMaxSum); } // max(left, right, crossSum) return Math.max(leftMaxSum + rightMaxSum + nums[mid], Math.max(left, right)); } }
functionLSS(list) { const len = list.length; let max = list[0]; for (let i = 1; i < len; i++) { list[i] = Math.max(0, list[i - 1]) + list[i]; if (list[i] > max) max = list[i]; }
return max; }
Java:
1 2 3 4 5 6 7 8 9 10 11
classMaximumSubarrayDP{ publicintmaxSubArray(int[] nums){ int currMaxSum = nums[0]; int maxSum = nums[0]; for (int i = 1; i < nums.length; i++) { currMaxSum = Math.max(currMaxSum + nums[i], nums[i]); maxSum = Math.max(maxSum, currMaxSum); } return maxSum; } }
Python 3:
1 2 3 4 5 6 7 8
classSolution: defmaxSubArray(self, nums: List[int]) -> int: dp = [0] * len(nums) ans = dp[0] = nums[0] for i in range(1, len(nums)): dp[i] = max(nums[i], dp[i - 1] + nums[i]) ans = max(ans, dp[i]) return ans
我们进一步分析,实际上我们只需要遍历一次计算出所有的 S(i), 其中 i 等于 0,1,2….,n-1。然后我们再减去之前的 S(k),其中 k 等于 0,1,i - 1,中的最小值即可。 因此我们需要 用一个变量来维护这个最小值,还需要一个变量维护最大值。
这种算法的时间复杂度 O(N), 空间复杂度为 O(1)。
其实很多题目,都有这样的思想, 比如之前的《每日一题 - 电梯问题》。
代码
JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
functionLSS(list) { const len = list.length; let max = list[0]; let min = 0; let sum = 0; for (let i = 0; i < len; i++) { sum += list[i]; if (sum - min > max) max = sum - min; if (sum < min) { min = sum; } }
return max; }
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classMaxSumSubarray{ publicintmaxSubArray3(int[] nums){ int maxSum = nums[0]; int sum = 0; int minSum = 0; for (int num : nums) { // prefix Sum sum += num; // update maxSum maxSum = Math.max(maxSum, sum - minSum); // update minSum minSum = Math.min(minSum, sum); } return maxSum; } }
Python 3:
1 2 3 4 5 6 7 8 9 10 11
classSolution: defmaxSubArray(self, nums: List[int]) -> int: n = len(nums) maxSum = nums[0] minSum = sum = 0 for i in range(n): sum += nums[i] maxSum = max(maxSum, sum - minSum) minSum = min(minSum, sum)