int num =Math.max(up[i-1],down[i-1]);boolean flag =true;//上一个石头默认是上坡if(num == down[i-1]) flag =false;//上一个石头是下坡if(flag) up[i]= up[i-1];//上一个也是上坡,那么摆动不变else up[i]= down[i-1]+1;//上一个是下坡,那么摆动+1
classSolution{publicintwiggleMaxLength(int[] nums){//和贪心一样int n = nums.length;if(n <2)return n;//dp数组表示,当前石块i,如果是上坡的,就放入up中,如果是下坡的,就放入down中,然后计算到这块石头为止的摆动//up表示上坡,down表示下坡。dp数组的下标表示,第几块石头//例如up[1],就是第一块石头如果是上坡,到它为止的路径,它的最大摆动是多少//down[3]就是第3块石头,如果是下坡,到它为止的路径,最大摆动是多少/**则dp数组的值保存的就是 到第i块石块,摆动的数量 */int[] up =newint[n];int[] down =newint[n];
up[0]= down[0]=1;//有石头就有一个摆动,无论上坡,还是下坡,都算一个摆动。for(int i =1; i < n; i++){//从第一块石头开始规划坡度if(nums[i]> nums[i -1]){//如果当前石块是上坡//当前石块应该放入上坡UP中,获取前一块石头的信息,前一块如果也是上坡,则摆动数量不变,前一块是下坡,那么摆动+1. //对于我们来说,我们不知道前一块是上坡还是下坡,但是上一块石头的路径摆动,一定放入了dp数组//而且一定是最大的,所以up[i-1]和down[i-1],就是获取前一块石头的最大摆动
up[i]=Math.max(up[i -1], down[i -1]+1);//必须两个一起获取,因为不知道前一块是上坡还是下坡//当前石块i是上坡,无法放入下坡,所以对于down来说,只能抛弃这块石头,那么摆动不变
down[i]= down[i -1];//让其继承前一块石头的坡度}elseif(nums[i]< nums[i -1]){//如果当前石块是下坡
up[i]= up[i -1];//和上坡没有关系,抛弃这块石头//获取前一块石头的信息,如果是上坡,那么摆动+1,如果是下坡,摆动不变。
down[i]=Math.max(up[i -1]+1, down[i -1]);}else{//如果是平坡
up[i]= up[i -1];//摆动不变
down[i]= down[i -1];//摆动不变}}//到最后一块石头石,我们也不知道最后一块是上坡还是下坡。只知道到它为止的摆动,放入了up[n-1]和down[n-1]//而且肯定是大的那个returnMath.max(up[n -1], down[n -1]);}}
3. 优化版动态规划
解题思路:时间复杂度O(
n
n
n),空间复杂度O(
1
1
1)
将法二的dp数组优化掉,换成了两个变量 因为法二中,虽然是dp数组,但是我们每次只使用前一个值罢了
代码
基于法二,单纯将数组换成变量
classSolution{publicintwiggleMaxLength(int[] nums){int n = nums.length;if(n <2)return n;int up =1, down =1;//将dp数组,换成两个变量for(int i =1; i < n; i++){if(nums[i]> nums[i -1]){//如果是上坡
up =Math.max(up, down +1);//看前一个是不是上坡,不是就摆动+1}elseif(nums[i]< nums[i -1]){//如果是下坡
down =Math.max(up +1, down);//上一个是上坡,就摆动+1}}returnMath.max(up, down);}}
classSolution{publicintwiggleMaxLength(int[] nums){int n = nums.length;if(n <2){return n;}int up =1, down =1;//将dp数组,换成两个变量for(int i =1; i < n; i++){if(nums[i]> nums[i -1]){//如果是上坡
up = down +1;//看前一个是不是上坡,不是就摆动+1}elseif(nums[i]< nums[i -1]){
down = up +1;}}returnMath.max(up, down);}}