[LC] 53. Maximum Subarray
Given an integer array nums
, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6.
Time:O(N)
Space:O(N)
//prefix
public class Solution { /** * @param nums: A list of integers * @return: A integer indicate the sum of max subarray */ public int maxSubArray(int[] nums) { // write your code here if (nums == null || nums.length == 0) { return 0; } int max = Integer.MIN_VALUE, min = 0, sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; max = Math.max(max, sum - min); min = Math.min(min, sum); } return max; } }
不能单纯求出prefixSum的最大值和最小值 然后相减 因为最小值有可能出现在最大值之后 那么这样就构不成一个subarray
所以 当沿着array index一个个往下走的时候 我们只需要知道“到目前为止“前面的prefix sum的最小值即可 而不是全局的最小值
用当前的prefixsum 减去 这个“到目前为止”的prefix sum的最小值 得到一个差 这个差即是当前这个数组成员为边界的subarray的和 用这个差更新最大值 最后数组走完了 这个差的最大值即是结果
這裡的思想是用當前的 prefix_sum 減去以前看過最小的 prefix_sum (ie min_sum) 再跟現有的 max_sum 比較,取較大的值更新 max_sum。因此如果我們先更新 min_sum ,會造成當我們遇到一個更小的 prefix_sum 時,prefix_sum - min_sum 這項永遠是 0,進而導致如 [-2, -1] 這種例子會出錯
//dp
1 class Solution: 2 def maxSubArray(self, nums: List[int]) -> int: 3 if nums is None or len(nums) == 0: 4 return 5 6 sum_arr = [0] * len(nums) 7 sum_arr[0] = nums[0] 8 max_res = nums[0] 9 for i in range(1, len(nums)): 10 if sum_arr[i - 1] > 0: 11 sum_arr[i] = nums[i] + sum_arr[i - 1] 12 else: 13 sum_arr[i] = nums[i] 14 max_res = max(max_res, sum_arr[i]) 15 return max_res
class Solution { public int maxSubArray(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int sum = nums[0], res = sum; for (int i = 1; i < nums.length; i++) { // add sum if sum > 0 sum = Math.max(nums[i], sum + nums[i]); res = Math.max(res, sum); } return res; } }