第一题:Leetcode376. 摆动序列
题目描述
解题思路
使用两个变量:preDiff 和 curDiff,分别记录 前一次相邻元素差值和 此处相邻元素值之差,只有当preDiff 和 curDiff 符号不同,摆动序列长度加一。
初始:长度为1。
题解1——贪心:移除坡上的元素。
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int ans = 1;int curDiff = 0, preDiff = 0;for (int i = 0; i < nums.size() - 1; i++) {curDiff = nums[i + 1] - nums[i];if ((preDiff >= 0 && curDiff < 0) ||(preDiff <= 0 && curDiff > 0)) {ans++;preDiff = curDiff;}}return ans;}
};
题解2——动态规划
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {// dp[i][0]表示考虑下标为i的元素以及之前的元素,i作为山峰的最长长度// dp[i][1]表示考虑下标为i的元素以及之前的元素,i作为山谷的最长长度vector<vector<int>> dp(nums.size() + 1, vector<int>(2, 0));dp[0][0] = dp[0][1] = 1;for (int i = 1; i < nums.size(); i++) {dp[i][0] = dp[i][1] = 1;for (int j = 0; j < i; j++) {// i作为山峰if (nums[i] > nums[j])dp[i][0] = max(dp[i][0], dp[j][1] + 1);// i作为山谷if (nums[i] < nums[j])dp[i][1] = max(dp[i][1], dp[j][0] + 1);}}return max(dp[nums.size() - 1][0], dp[nums.size() - 1][1]);}
};
要点
- dp数组的意义:dp[i][0]表示考虑下标为i的元素以及之前的元素、i作为山峰的最长长度; dp[i] [1]表示考虑下标为i的元素以及之前的元素、i作为山谷的最长长度。
- 初始化:dp[i][0]和dp[i][1]均初始化为1(表示
这个元素本身就可以作为波峰或者波谷)。class Solution { public:int maxSubArray(vector<int>& nums) {int ans = INT_MIN;int count = 0;for (int i = 0; i < nums.size(); i++) {count += nums[i];if (count > ans) {ans = count;}if (count < 0)count = 0;}return ans;} };
- 递推方法:对于所有j大于0、小于i,依次比较计算dp[i][0]和dp[i][1]
第二题:Letcode53. 最大子数组和
题目描述
题解1
class Solution {
public:int maxSubArray(vector<int>& nums) {int ans = INT_MIN;int count = 0;for (int i = 0; i < nums.size(); i++) {count += nums[i];if (count > ans) {ans = count;}if (count < 0)count = 0;}return ans;}
};
如果 count < 0,则后续计算不加上 nums[i]。
题解2——动态规划
class Solution {
public:int maxSubArray(vector<int>& nums) {vector<int> dp(nums.size()); // dp[i]表示 以0 <= j <= i开始、以 i 结尾// 的最大子数组和dp[0] = nums[0];int ans = dp[0];for (int i = 1; i < nums.size(); i++) {dp[i] = max(dp[i - 1] + nums[i], nums[i]);if (dp[i] > ans) {ans = dp[i];}}return ans;}
};