LeetCode376---摆动序列

115 篇文章 0 订阅
41 篇文章 0 订阅

题目描述

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。

例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

示例1:

输入: [1,7,4,9,2,5]
输出: 6 
解释: 整个序列均为摆动序列。

示例2:

输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]

示例3:

输入: [1,2,3,4,5,6,7,8,9]
输出: 2

解题思路:使用贪心思想。
当数列部分区间为连续递增或者连续递减的时候,选取区间中最大的值,这样可以尽可能使下一个数字组成摆动序列

解法一:波峰和波谷之间差1。(leetcode大神的想法)

int wiggleMaxLength(vector<int>& nums) {//波峰和波谷相差为1
	// [1,17,5,10,13,15,10,5,16,8]
	if (nums.size() < 2) {
		return nums.size();
	}
	int up = 1;//波峰起始为1
	int down = 1;//波谷起始为1
	for (int i = 1; i < nums.size(); i++) {
		if (nums[i-1] < nums[i]) {
			//上升序列
			up = down + 1;
		}
		if (nums[i] < nums[i - 1]) {
			//下降序列
			down = up + 1;
		}
	}
	return max(up,down);
}

解法二:使用标志位来判断是递增序列还是递减序列

int wiggleMaxLength(vector<int>& nums) {//使用标志位来判断
	if (nums.size() < 2) {
		return nums.size();
	}
	int max_length = 1;//序列的最大长度
	int flag = 1;//标志位
	bool start = true;//起始标志位,处理第一个数字
	for (int i = 1; i < nums.size(); i++) {
		if (nums[i - 1] < nums[i] && (flag == 1 || start)) {//上升序列
			max_length++;
			flag = -1;
			start = false;
		}
		else if(nums[i] < nums[i-1] && (flag == -1 || start))//下降序列
		{
			max_length++;
			flag = 1;
			start = false;
		}
	}
	return max_length;
}

解法三:使用状态机来实现,此种方法思路清晰,代码可读性强

int wiggleMaxLength2(vector<int>& nums) {//使用状态机实现
	if (nums.size() < 2) {
		return nums.size();
	}
	static const int BEGIN = 0;//开始状态
	static const int UP = 1;//上升状态
	static const int DOWN = 2;//下降状态
	int STATE = BEGIN;
	int max_length = 1;//序列长度最少为1
	for (int i = 1; i < nums.size(); i++) {
		switch (STATE)
		{
		case BEGIN:
			if (nums[i - 1] < nums[i]) {
				STATE = UP;
				max_length++;
			}
			if (nums[i] < nums[i - 1]) {
				STATE = DOWN;
				max_length++;
			}
			break;
		case UP:
			if (nums[i] < nums[i - 1]) {
				STATE = DOWN;
				max_length++;
			}
			break;
		case DOWN:
			if (nums[i - 1] < nums[i]) {
				STATE = UP;
				max_length++;
			}
			break;
		default:
			break;
		}
	}
	return max_length;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值