Skip to content

Latest commit

 

History

History
106 lines (91 loc) · 3.82 KB

53.最大子数组和.md

File metadata and controls

106 lines (91 loc) · 3.82 KB
贪心算法 or 动态规划

思路:如[-2,1,-3,4,-1,2,1,-7,4],从头开始遍历,如果自己是负数需要警惕,即自己或自己之前的和是负数,
此时可以sum=0重新计算,因为前面的负数是不做贡献的。从遇到的第1个正数开始累加sum,如果遍历累加过程中,
sum又变为负数,则重新清零,直到遇到下一个正数为止。

注:此题很容易分析成滑动窗口(slow,fast)类型,但是敏锐观察发现slow不满足条件后是跳变到fast,不是slow++
逐次递增,所以考虑是否为贪心算法or动态规划等。
注:sum累加为负后,必须再要跳到下一个正数,否则“耽误”找最大值。
注:核心在于要想到,sum不能累加为负,一旦累加为负就会成为“累赘”,应该“清零”并等待跳到下一个正数重新开始。
注:一般情况下,满足要求的序列两端一定是正数,所以想到要sum从正数开始。
注:遍历到最右端如果遇到如[...,-7,5],容易出现干扰思想,其实不用管,只要之前的sum-7仍然为正,那么可以
继续囊括[-7,5],可能会觉得sum变小了不好,其实不重要,因为ans的最大值之前已经记录下来了,即使sum变小了,
它此时也是个正值,会继续给后面做“贡献”(如果后面还有的话)。
注:此题贪心算法解法,sum其实有巧妙之处难以想到,后续学习动态规划看是否可以常规思路解决。

1:学会用INT32_MIN表示最小值。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int ans = INT32_MIN; // wyh 1
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
            ans = max(sum, ans);
            if (sum <= 0) sum = 0;
        }
        return ans;
    }
};

滑动窗口(快慢双指针)

思路:和上面贪心算法的思路一样。

注:观察可发现slow不满足条件后是跳变到fast,不是slow++逐次递增,所以考虑是否不需要滑动窗口快慢指针,
为其他如贪心算法or动态规划等。
注:slow实际上没起作用,因为没有nums[slow]等。

1:模板这里是while,此题灵活换成if2:模板这里是两步,窗口扩大:a)加入fast元素;b)更新当前result值。不一定在这个位置,具体情况具体考虑。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0, ans = INT32_MIN;
        int slow = 0, fast = 0;
        while (fast < nums.size()) {
            sum += nums[fast];
            ans = max(sum, ans); // wyh 2
            if (sum <= 0 && slow <= fast) // wyh 1
            {
                slow = fast;
                sum = 0;
            }
            fast++;
        }
        return ans;
    }
};

// 复习
// slow不需要起作用,只需要fast直接遍历一遍即可,即for(i)遍历一遍
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0, ans = INT32_MIN;
        int slow = 0, fast = 0;
        while (fast < nums.size()) {
            sum += nums[fast];
            ans = max(sum, ans); // wyh 2
            if (sum <= 0) // wyh 1
            {
                sum = 0;
            }
            fast++;
        }
        return ans;
    }
};

// 复习 动态规划 class Solution { public: int maxSubArray(vector& nums) { if (nums.size() == 0) return 0; if (nums.size() == 1) return nums[0];

  vector<int> dp(nums.size());
  dp[0] = nums[0];
  for (int i = 1; i < nums.size(); i++) {
    dp[i] = (dp[i - 1] > 0 ? dp[i - 1] : 0) + nums[i];
    // printf("dp[%d]:%d %d %d %d\n", i, dp[i], dp[i - 1], (dp[i - 1] > 0), nums[i]);
  }

  // for_each(dp.begin(), dp.end(), [](int& val) {
  //   cout << val << " ";
  // });

  return *max_element(dp.begin(), dp.end());
}

};