053J. Maximum Subarray
https://leetcode.com/problems/maximum-subarray/
Method: Best 1, Dynamic Programming.
思想大致类似于
如果前面部分的和是负数,那么对我就是负影响,直接丢弃,
如果是正数,可以加入子数组。
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0];
for(int i = 1; i < nums.length; i+= 1){
if(nums[i-1] > 0) nums[i] += nums[i-1];
ans = Math.max(ans,nums[i]);
}
return ans;
}
}
Method: Best 2, Greedy.
类似于,我们保存一个局部最大,和全局最大。
局部最大就是,如果局部最大加上当前nums[i],还不如nums[i]大,
说明局部最大目前是负数,而nums[i]是正数,直接取nums[i]。反之,如果nums[i]是负数,
则局部最大加nums[i]比较大,存下局部最大加nums[i].
全局最大一直做比较,所有的局部最大中最大的一定是全局最大,这就是贪心法。
class Solution {
public int maxSubArray(int[] nums) {
int curSum = nums[0];
int maxSum = nums[0];
for(int i = 1; i < nums.length; i++){ //从1开始是防止edge case 以免写开头的 if return
curSum = Math.max(nums[i],curSum+nums[i]);
maxSum = Math.max(maxSum,curSum);
}
return maxSum;
}
}
53 放一个 2023 年写的写法,一个思路到是。这个题的解法有个名字叫 Kadane's algo
class Solution {
public int maxSubArray(int[] nums) {
int max = Integer.MIN_VALUE;
int[] prefixSum = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i];
}
int left = 0;
for (int right = 1; right < prefixSum.length; right++) {
int curSum = prefixSum[right] - prefixSum[left];
max = Math.max(curSum, max);
if (curSum < 0) {
left = right;
}
}
return max;
}
}
2272 也是用到了 Kadane's algo
Last updated
Was this helpful?