zoukankan      html  css  js  c++  java
  • LeetCode.376

      求最长摆动子序列。

      Examples:

      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

      这个题很有意思,有很多种解法,用来练练dp...然而还是看题解才会的orz

      一个普通dp代码:

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    #include <minmax.h>
    
    using namespace std;
    
    class Solution {
    public:
    	int wiggleMaxLength(vector<int>& nums) {
    		if (nums.empty())
    			return {};
    		if (nums.size() < 2)
    			return nums.size();
    
    		vector<int> up(nums.size());
    		vector<int> down(nums.size());
    
    		for (int i = 1; i < nums.size(); i++)
    			for (int j = 0; j < i; j++)
    			{
    				if (nums[i] > nums[j])
    					up[i] = max(up[i], down[j] + 1);
    				else if (nums[i] < nums[j])
    					down[i] = max(down[i], up[j] + 1);
    			}
    		return 1 + max(up[nums.size() - 1], down[nums.size() - 1]);
    	}
    };
    
    int main()
    {
    	vector<int> nums{ 1,17,5,10,13,15,10,5,16,8 };
    	
    	cout << Solution().wiggleMaxLength(nums) << endl;
    
    	getchar();
    	return 0;
    }
    

      运行结果:

    7

      时间复杂度O(n^2),空间复杂度O(n)。

      重点是这个优化的dp算法,时间复杂度O(n),空间复杂度O(1):

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    #include <minmax.h>
    
    using namespace std;
    
    class Solution {
    public:
    	int wiggleMaxLength(vector<int>& nums) {
    		if (nums.empty())
    			return {};
    		if (nums.size() < 2)
    			return nums.size();
    
    		int up = 1, down = 1;
    		for (int i = 1; i < nums.size(); i++)
    		{
    			if (nums[i] > nums[i - 1])
    				up = down + 1;
    			else if (nums[i] < nums[i - 1])
    				down = up + 1;
    		}
    		return max(up, down);
    	}
    };
    
    int main()
    {
    	vector<int> nums{ 1,17,5,10,13,15,10,5,16,8 };
    	
    	cout << Solution().wiggleMaxLength(nums) << endl;
    
    	getchar();
    	return 0;
    }
    

      运行结果:

    7
    

      这个算法实在又简洁又易懂。

  • 相关阅读:
    逆元模板
    同余方程
    计算系数
    Mayan游戏
    【分治】聪明的质检员(二分)
    瑞士轮(归并排序)
    极值问题
    传纸条
    2014-2015-1学期学习计划
    桌面综合实训答辩验收详情
  • 原文地址:https://www.cnblogs.com/darkchii/p/8571309.html
Copyright © 2011-2022 走看看