LeetCode 376. 摆动序列

贪心算法

int wiggleMaxLength(vector<int> &nums) {
	if (nums.size() <= 1) {
	    return nums.size();
	}
	
	int currDiff;
	int preDiff = 0;
	int res = 1;
	for (int i = 0; i < nums.size() - 1; ++i) {
	    currDiff = nums[i + 1] - nums[i];
	
	    if ((currDiff > 0 && preDiff <= 0) || (currDiff < 0 && preDiff >= 0)) {
	        res++;
	        preDiff = currDiff;
	    }
	}
	return res;
}
  1. 为什么判断preDiff的时候要带上等号?
    答:因为题目要求判断nums的子序列,子序列就是可以忽略其中一些点,也就是说如果出现差值是0的情况,只要两侧满足差值一正一负,也符合要求。
    LeetCode 376. 摆动序列_第1张图片

    如图,这两种情况都符合条件,所以判断preDiff的时候要加上等于0的判断。

  2. 为什么结果res的初始值是1?
    按照题目要求:“仅有一个元素或者含两个不等元素的序列也视作摆动序列”,仅有一个元素的情况,已经使用单独的if进行判断了。
    如果含有两个相同元素,或者所有的元素都相同,那么最后结果就是1;
    除此之外,如果含有两个不同元素,在初始preDiff=0的情况下,肯定能进入if判断一次,导致res增加变成2。

  3. 为什么preDiff = currDiff要放在if里面?
    还有一种preDiff=0,并且可以进入if的情况,但是不符合条件:递增的中间出现直线。
    LeetCode 376. 摆动序列_第2张图片
    首先可以明确的是图示这种情况不符合条件。
    如果每次都执行preDiff = currDiff,那么1-2和4-5都会被计入结果,这是不对的。
    出现问题的环节是4位置出现的preDiff,判断是否出现波峰,应该和上一个非0的差值,也就是1比较,如果和0差值比较,就不知道到底是波峰还是如图的问题。
    所以需要记住前一个非0的Diff,也就是说当Diff等于0的时候,不要去执行preDiff = currDiff赋值操作。
    LeetCode 376. 摆动序列_第3张图片
    当出现上图的情况(currDiff==0)时,不要执行preDiff = currDiff,而是继续向后计算currDiff。
    LeetCode 376. 摆动序列_第4张图片
    直到出现这种情况,再去比较currDiff和preDiff,就能准确判断情况。

你可能感兴趣的:(leetcode,算法)