动态规划设计:最大子数组 :: labuladong的算法小抄 #985
Replies: 24 comments 6 replies
-
状态方程有个条件少了,对于 特殊case |
Beta Was this translation helpful? Give feedback.
-
如果dp[i - 1] <= 0,max函数返回的也是nums[i]。不需要额外判断 |
Beta Was this translation helpful? Give feedback.
-
这是不是一种贪心思想。 |
Beta Was this translation helpful? Give feedback.
-
用一个变量就可以表示状态转移的过程了,因为最终求解的时候,旧状态是用过即弃的,不需要保留它。 换句话说,在状态压缩的题解代码里: dp_1 = Math.max(nums[i], nums[i] + dp_0);
dp_0 = dp_1;
dp = Math.max(nums[i], nums[i] + dp); |
Beta Was this translation helpful? Give feedback.
-
这个应该就是Kadane's algorithm |
Beta Was this translation helpful? Give feedback.
-
其实本题可以利用滑动窗口去解决,每次记录了当前的最大值即可 class Solution
{
public int maxSubArray(int[] nums) {
int left=0;
int right=0;
int sum=0;
int maxsum=nums[0];
while(right<nums.length())
{
sum+=nums[right];
if(sum<0)
{
sum-=nums[left];
left++;
}
//进行答案的更新
maxsum=Math.max(maxsum,sum);
}
//进行特殊情况的处理
int maxVal = nums[0];
for (int i = 1; i <nums.size(); i++) {
maxVal = max(maxVal, nums[i]);
}
return maxVal < 0 ? maxVal : maxsum;
}
} |
Beta Was this translation helpful? Give feedback.
-
以nums[i]结尾的最大子数组和情况之二和前面连成一个数组,但如何保证和前面的一定是连续的呢 |
Beta Was this translation helpful? Give feedback.
-
本题的滑动窗口解法,重点在于maxSum的初始化 class Solution {
public:
int maxSubArray(vector<int>& nums) {
// 滑动窗口(快慢指针
int left = 0, right = 0;
int sum = 0, maxSum = INT32_MIN; // 重点:preMaxSum一定要设置为最小负数,这样遇到全负数组的时候才能不出错
while(right < nums.size()){
// 移入
int c = nums[right];
// 增大窗口
right++;
// 更新窗口
sum += c;
maxSum = sum > maxSum ? sum : maxSum;
// 判断左侧窗口是否要收缩
while(sum < 0){
// 移除
int d = nums[left];
// 缩小窗口
left++;
// 更新窗口
sum -= d;
}
}
return maxSum;
}
}; |
Beta Was this translation helpful? Give feedback.
-
// 要么自成一派,要么和前面的子数组合并 |
Beta Was this translation helpful? Give feedback.
-
@mianbao374 没错,dp的定义就是以num[i]为结尾的[最大子数组和],dp[n-1]确实是7,但是问题求的最终结果是dp数组的最大值max(dp[i])=dp[1]=9,你应该是看漏了 |
Beta Was this translation helpful? Give feedback.
-
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int subSum=0;
int result=INT_MIN;
for(int i=0;i<nums.size();i++){
subSum=max(subSum+nums[i],nums[i]);
result=max(result,subSum);
}
return result;
}
}; |
Beta Was this translation helpful? Give feedback.
-
明白了,是我看漏了 |
Beta Was this translation helpful? Give feedback.
-
确实,看了下评论区读者的讨论,本题可以用滑动窗口算法,我这两天把滑动窗口算法的思路补充到文章中 |
Beta Was this translation helpful? Give feedback.
-
有谁能给个 dp 函数的解法 |
Beta Was this translation helpful? Give feedback.
-
摩尔投票 public int maxSubArray(int[] nums) {
int n = nums.length;
int sum = 0;
int res = Integer.MIN_VALUE;
for(int num : nums){
if(sum < 0){
sum = num;
}else{
sum += num;
}
res = Math.max(res, sum);
}
return res;
} |
Beta Was this translation helpful? Give feedback.
-
Prefix sum相减: class Solution {
public int maxSubArray(int[] nums) {
int minSum = Integer.MAX_VALUE;
int sum = 0;
int result = Integer.MIN_VALUE;
for (int num: nums){
minSum = Math.min(sum, minSum);
sum+=num;
result = Math.max(sum-minSum, result);
}
return result;
}
} |
Beta Was this translation helpful? Give feedback.
-
打卡打卡 滑动窗口不可以 |
Beta Was this translation helpful? Give feedback.
-
文中的滑动窗口写法有误,不符合 窗口内元素之和大于等于 0 时扩大窗口,在窗口内元素之和小于 0 时缩小窗口,在每次移动窗口时更新答案 int maxSubArray(int* nums, int numsSize)
{
int l = 0, r = 0;
int winSum = 0, maxSum = -INT_MAX;
while(r < numsSize) {
if (winSum >= 0) {
winSum += nums[r];
r++;
}
maxSum = maxSum > winSum ? maxSum : winSum;
if (winSum < 0) {
winSum -= nums[l];
l++;
}
}
return maxSum;
} |
Beta Was this translation helpful? Give feedback.
-
打卡,多种解题思路,学习了! |
Beta Was this translation helpful? Give feedback.
-
int maxSubArray(vector& nums) { |
Beta Was this translation helpful? Give feedback.
-
int left = 0;
|
Beta Was this translation helpful? Give feedback.
-
打卡!!希望东哥这个网站能够一直维护啊,太宝藏了 |
Beta Was this translation helpful? Give feedback.
-
滑动窗口这个好巧妙,说实话还有几分迷糊,每当窗口里数字和小于0的时候,窗口不断缩小,左右指针重合,窗口变为0(想几种情况,应该是一定会窗口变为0),再开始扩大窗口,所以不会漏掉正数开头的情况 |
Beta Was this translation helpful? Give feedback.
-
文章链接点这里:动态规划设计:最大子数组
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions