这道题,求摆动序列的最长长度和之前做过的一道求序列的
最长上升子序列
类似,不同的是本题无法用一个数组来记录以i
结尾的最长上升子序列,因为摆动数组的每一个元素既可以是最长摆动子序列下降后的元素,也可以是上升后的元素
因此,可以用两个数组维护,最长上升子序列与最长下降子序列,对于当前
元素进行判断
,若nums[i]-nums[j]
则应该从nums[j]所处的下降序列中找最长
/**
* 本题和最长上升子序列类似
* 不同的是本题无法用一个数组来记录以i结尾的最长上升子序列,因为摆动数组的没每一个元素既可以是
* 最长摆动子序列下降后的元素,也可以是上升后的元素
*
* nums = [1,17,5,10,13,15,10,5,16,8]
nums[2] 即数值 5, 既可以属于 [1, 5] 与前一个相比为上升, 也可以属于 [1, 17, 5] 与前一个相比为下降, 由于不知道后面数子的情况, 所以 5 属于这两种不同情况的数值也必须保留
所以, 可以使用 up 和 down 两个数组分别记录 n 属于这两种状态下的最长摆动序列
定义即是: up 代表以 nums[i] 结尾的最长摆动序列的长度, 并且 nums[i] 位置的元素相比于上一个元素是上升的, 那么上例中 up[2] 为 2 down[2] 为 3
*
*
*
* @param nums
* @return
*/
public int wiggleMaxLength1(int[] nums){
if(nums.length==0) return 0;
//当前元素处于上升的序列
int[] dpUp = new int[nums.length];
//当前元素处于下降的序列
int[] dpDown = new int[nums.length];
for(int i=0;i<nums.length;i++){
dpDown[i]=1;
dpUp[i]=1;
}
for(int i=1;i<nums.length;i++){
for(int j=0;j<i;j++){
// 说明 nums[j] -> nums[i]
// 是一个下降的过程,
// 那么只有在最长摆动序列中 nums[i] 位置的元素属于上升元素时,
// 此处的 nums[i] 才可以把它给延长, 并且延长后 nums[i] 位置本身是属于下降的元素
if(nums[j] > nums[i]){
dpDown[i]=Math.max(dpDown[i],dpUp[j]+1);
}else if(nums[j]<nums[i]) {//说明是上升的元素
dpUp[i] = Math.max(dpUp[i], dpDown[j] + 1);
} //元素相等的话则不作任何处理
}
}
int max = 0;
//从记录中找到最长的,这部分代码也可以融入到前面的动态规划中,动态更新全局最大值
for(int i=0;i<nums.length;i++){
max =Math.max(dpDown[i],dpUp[i]);
}
return max;
}
2020/8/4
/**定义两个变量up:代表上升摆动序列的长度 。down:代表下降摆动序列的长度。
1 nums[i]>nums[i-1]则说明这个摆动序列在上升,此时上升摆动序列长度=下降摆动序列+1(加1是加的nums[i])
2 nunm[i]<nums[i-1]则说明这个摆动序列在下降,此时下降摆动序列长度=上升摆动序列+1(加1是加的nums[i])**/
public int wiggleMaxLength1(int[] nums) {
if(nums.length<2) return nums.length;
int down=1;
int up=1;
for(int i=1;i<nums.length;i++){
if(nums[i]>nums[i-1]){
up=down+1;
}else if(nums[i]<nums[i-1]){
down=up+1;
}
}
return Math.max(up,down);
}