LeetCode——376.摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/wiggle-subsequence
动态规划
我们维护两个dp数组p和q,其中
p[i]表示到i位置时首差值为正的摆动子序列的最大长度,
q[i]表示到i位置时首差值为负的摆动子序列的最大长度。
我们从i=1开始遍历数组,然后对于每个遍历到的数字,再从开头位置遍历到这个数字,
然后比较nums[i]和nums[j],分别更新对应的位置,参见代码如下:
C++
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.empty()) return 0;
        vector<int> p(nums.size(), 1);
        vector<int> q(nums.size(), 1);
        for (int i = 1; i < nums.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                if      (nums[i] > nums[j]) p[i] = max(p[i], q[j] + 1);
                else if (nums[i] < nums[j]) q[i] = max(q[i], p[j] + 1);
            }
        }
        return max(p.back(), q.back());
    }
};
java
public class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length < 2)
            return nums.length;
        int[] p = new int[nums.length];
        int[] q = new int[nums.length];
        for (int i = 1; i < nums.length; i++) {
            for(int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    p[i] = Math.max(p[i],q[j] + 1);
                } else if (nums[i] < nums[j]) {
                    q[i] = Math.max(q[i],p[j] + 1);
                }
            }
        }
        return 1 + Math.max(q[nums.length - 1], p[nums.length - 1]);
    }
}
java优化
public class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length < 2)
            return nums.length;
        int[] p = new int[nums.length];
        int[] q = new int[nums.length];
        p[0] = q[0] = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) {
                p[i] = q[i - 1] + 1;
                q[i] = q[i - 1];
            } else if (nums[i] < nums[i - 1]) {
                q[i] = p[i - 1] + 1;
                p[i] = p[i - 1];
            } else {
                q[i] = q[i - 1];
                p[i] = p[i - 1];
            }
        }
        return Math.max(q[nums.length - 1], p[nums.length - 1]);
    }
}
Python
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if not nums:
            return 0
        res = []
        dp = [[1 for i in range(2)] for j in range(len(nums))]
        res.append(dp[0][0])
        res.append(dp[0][1])
        for i in range(1,len(nums)):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i][1] = max(dp[i][1],dp[j][0]+1)
                elif nums[i] < nums[j]:
                    dp[i][0] = max(dp[i][0],dp[j][1]+1)
                else:               #若nums[i]=nums[j],此时nums[i]不可能加在nums[j]后面
                    continue
            res.append(dp[i][0])
            res.append(dp[i][1])
        return max(res)
# dp[i][0]表示以nums[i]结尾且当前位置为降序的最长摆动序列,
# dp[i][1]表示以nums[i]结尾且当前位置为升序的最长摆动序列
贪心算法
这里我们不在维护两个dp数组,而是维护两个变量p和q,然后遍历数组,
如果当前数字比前一个数字大,则p=q+1,如果比前一个数字小,则q=p+1,
最后取p和q中的较大值跟n比较,取较小的那个,参见代码如下:
C++
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int p = 1, q = 1, n = nums.size();
        for (int i = 1; i < n; ++i) {
            if (nums[i] > nums[i - 1]) p = q + 1;
            else if (nums[i] < nums[i - 1]) q = p + 1;
        }
        return min(n, max(p, q));
    }
};
Java
public class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length < 2) return nums.length;
        int q = 1, p = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) p = q + 1;
            else if (nums[i] < nums[i - 1]) q = p + 1;
        }
        return Math.max(q, p);
    }
}
												
											LeetCode——376.摆动序列的更多相关文章
- Java实现 LeetCode 376 摆动序列
		
376. 摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5 ...
 - Leetcode 376.摆动序列
		
摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个 ...
 - 【LeetCode】NO.376 摆动序列 (Python) [贪心算法]
		
376. 摆动序列 题目 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 .第一个差(如果存在的话)可能是正数或负数.仅有一个元素或者含两个不等元素的序列也视作摆动序列. 例 ...
 - [Leetcode 376]摇摆序列 Wiggle Subsequence
		
[题目] A sequence of numbers is called a wiggle sequence if the differences between successive numbers ...
 - [Swift]LeetCode376. 摆动序列 | Wiggle Subsequence
		
A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...
 - ALGO-9_蓝桥杯_算法训练_摆动序列(DP)
		
问题描述 如果一个序列满足下面的性质,我们就将它称为摆动序列: . 序列中的所有数都是不大于k的正整数: . 序列中至少有两个数. . 序列中的数两两不相等: . 如果第i – 1个数比第i – 2个 ...
 - Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
		
正整数的摆动序列 问题描述 如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列.即 a[2i]<a[2i-1], a[2i+1]>a[2i]. 小明想知道,长度为 m ...
 - Java实现 蓝桥杯VIP 算法训练 摆动序列
		
问题描述 如果一个序列满足下面的性质,我们就将它称为摆动序列: 1. 序列中的所有数都是不大于k的正整数: 2. 序列中至少有两个数. 3. 序列中的数两两不相等: 4. 如果第i – 1个数比第i ...
 - SYCOJ2100摆动序列
		
题目-摆动序列 (shiyancang.cn) 直接分成两部分,插入即可.只有一个地方不对,那就是符号.两个大的放一个小的,两个小的放一个大的.那么每次的大的放最大的,每次的小的放其次小的,用完就不用 ...
 
随机推荐
- java类加载及new对象的过程
			
/* SubClass sub = new SubClass(); 这句话到底做了什么事情呢? 1.javac编译.java源文件形成.class字节码文件; 2.new SubClass()对象时, ...
 - 标准JAVA工程结构
 - python刷LeetCode:20. 有效的括号
			
难度等级:简单 题目描述: 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序 ...
 - Hibernate(二)——一对多查询
			
1. 前言 本章节我们讨论Hibernate一对多查询的处理. 在上一章节中(Hibernate(一)——入门),我们探讨了Hibernate执行最基本的增删改查操作.现在我们将情况复杂化:加入我们在 ...
 - python try-except处理异常的常用方法分析
			
在写python程序时遇到异常想要进行处理时,可以使用try-except来处理,例如: try: 语句1 语句2 . . 语句N except .........: do something ... ...
 - 越南CTF的crypto 100
			
自己做CTF还是没有经验,本来以为crypto更多应该是python编程的,结果这个100的题目是Do you love Arithmetic? 打开文件来看内容是 # charset = " ...
 - solr8.0.0基本安装和在springboot中的基本使用(win10)
			
1.下载solr 下载地址:http://archive.apache.org/dist/lucene/solr/ 该地址可以也可以下载以前的版本,我这边下载的solr-8.0.0.zip版本.下载完 ...
 - Java模板引擎之Freemarker 学习笔记  一
			
什么是Freemarker Freemarker是模板引擎,不是Web框架,只是视图层的组件,官网是 https://freemarker.apache.org/ Freemarker原理 数据模型+ ...
 - 【每日Scrum】第七天冲刺
			
一.计划会议内容 界面ui制作,主界面进度 二.任务看板 三.scrum讨论照片 四.产品的状态 无 五.任务燃尽图
 - ZOJ 2301/HDU 1199 线段树+离散化
			
给这个题目跪了两天了,想吐简直 发现自己离散化没学好 包括前一个离散化的题目,实际上是错了,我看了sha崽的博客后才知道,POJ那题简直数据弱爆了,本来随便一组就能让我WA掉的,原因在于离散化的时候, ...