Wiggle Subsequence

来源:互联网 发布:精业本草官方淘宝店 编辑:程序博客网 时间:2024/05/23 19:19

题目来源

输入一个整型数组nums,该数组表示一个序列,序列中元素的大小顺序是随机的。从数组中去除若干个元素后,可以得到wiggle sequence。求能够得到的最长wiggle sequence的长度。
wiggle sequence是一种满足相邻元素的差值严格遵循正负交替特点的序列。长度为1的序列都算作wiggle sequence。
例如:
Input: [1,7,4,9,2,5]
Output: 6
The entire sequence is a wiggle sequence.
Input: [1,17,5,10,13,15,10,5,16,8]
Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
Input: [1,2,3,4,5,6,7,8,9]
Output: 2

---------------------------
题目要求时间复杂度为O(n),可以考虑用空间换时间——采用DP(动态规划)的思想来解决这个问题。
(1)首先考虑一般情况
创建两个辅助数组lengths和diffs,其元素分别用于记录序列从最左边到当前位置为止,所能得到的最长wiggle sequence的长度和当前元素在wiggle sequence中相对于前一个元素的差值。
在已知lengths[k] 和diffs[k]的情况下,可以用下面的方法将lengths和diffs推进到k+1:
首先求出序列中第k+1个元素与第k个元素的差值,即diff = nums[k + 1] – nums[k]。根据diff的不同进行不同的处理:
1)diff = 0,说明这两个元素相等,此时lengths[k + 1] = lengths[k],diffs[k + 1] = diffs[k];
2)diff与diffs[k]同为正数或同为负数,说明这两个元素中需要去除一个,因此到k+1位置为止的最长wiggle subsequence长度与k的相同,此时lengths[k + 1] = lengths[k],diffs[k + 1] = diff;
2)diff与diffs[k]不同号,说明可以在k的最长wiggle subseequence的基础上追加一个元素nums[k + 1]。此时lengths[k + 1] = lengths[k] + 1,diffs[k + 1] = diff。
(2)空间复杂度的优化
事实上,对于上述两个辅助数组lengths和diffs,每次迭代时都只用到了最近的一个元素。因此,可以将这两个数组简化为两个变量——maxlen和diff。
(3)考虑边界条件
上述算法从序列的第2个元素开始处理,直到序列的最后一个元素,最后得到的lengths的最后一个元素即为整个序列的最长wiggle subsequence的长度。
如果输入序列含有0元素,那么直接返回0。另外,diff的初始值没有意义,因此需要在迭代时进行判断。

实现代码如下:

class Solution {    public int wiggleMaxLength(int[] nums) {        if(nums.length == 0) {            return 0;        }                int maxlen = 1, diff = 0;        for(int i = 1; i < nums.length; i++) {            int newDiff = nums[i] - nums[i - 1];            if(newDiff != 0 && (diff == 0 || newDiff * diff < 0)) {                diff = newDiff;                maxlen++;            }        }                return maxlen;    }}
算法只需要进行一轮迭代并且只用到了有限个状态变量,因此时间复杂度为O(n),空间复杂度为O(1)。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为账号手机号显示已被注册怎么办 买了鑫和陌车的怎么办 注册游戏账号时乱输入的邮箱怎么办 yy频道解邦不能开直播怎么办 淘宝的淘金币快过期了怎么办 乐透啦彩票让骗了6万怎么办 交了认筹金不能进抢购平台怎么办 爱奇艺会文学会员办了想退款怎么办 海淘信用卡入账但是砍单怎么办 褐色分泌物流了好几天了怎么办? 淘宝买的衣服一直不发货怎么办 从国外寄东西到国内被税了怎么办 百度网盘上传文件数量有限制怎么办 腾讯视频上传文件过限制大小怎么办 三星s7打网页又卡又慢怎么办 路由器的上网账号和口令忘了怎么办 小米笔记本移动热点连接不上怎么办 移动宽带密码重置后认证失败怎么办 移动光纤不记得账号和密码怎么办? 宽带为什么交了钱还是不能用怎么办 小孩被虎牙直播诱导支付了款怎么办 房间里4g网络信号差怎么办 移动4g网络信号不满格怎么办 大风号无法上传视频暂停服务怎么办 过了竞牌保证金交付时间怎么办 亚马逊产品上架后货物没到怎么办 工行企业网银证书过期了怎么办 海淘转运地址国家填错了怎么办 集装箱实重与申报重量不一样怎么办 微博复制的淘口令找不到了怎么办 买了移动手机不能用联通卡怎么办 移动手机用联通卡网速慢怎么办 移动手机插联通卡没反应怎么办 移动手机办了联通大王卡怎么办 qq被冻结但是有至尊宝怎么办 qq被冻结了有至尊宝怎么办 移动电话卡注销了里面的钱怎么办 罗麦的oa上经理喜报没截图怎么办 工行融e联登录密码忘了怎么办 融e借有额度秒拒怎么办 工行银行柜台办理融e借怎么办