Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.
本题标签为binary search和dinamic programming
法一: binary search
观察最长的increasing subsequence都有什么特点:1.如果碰到新的数字比当前的increasing subsequence的最大值要小并且于这个数列之前所有的数构成递增数列的话 最优解一定可以换成小的这个数 2.对于“潜力股”数列 怎么同时培养比较呢?由于“潜力股”数列数字小所以并不影响后边大数增加序列长度 既新遇到的大数既可以增加原数列的长度 又可以增加新数列的长度 所以找到原数列对应位置改成新数字做考察
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 vector<int> res; 5 for(int i = 0; i < nums.size(); i++) 6 { 7 auto it = std::lower_bound(res.begin(), res.end(), nums[i]); 8 if(it != res.end()) 9 *it = nums[i]; 10 else 11 res.push_back(nums[i]); 12 } 13 return res.size(); 14 } 15 };
法二:dp
同样是潜力股的问题 和上一种方法类似需记录不同长度的子序列结尾的最小值以便后续培养 dp[i]表示长度为i的子序列结尾的最小值
遍历的时候碰到新的数字时如果比dp最后长序列的末尾大那么目前为止最长的序列加上这个数就成为最长的序列以这个数为结尾 如果比最后一个数小 那么一定有一个中间长度的子序列可以以这个数为结尾
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 vector<int> dp; 5 if(nums.size() == 0) 6 return 0; 7 dp.push_back(nums[0]); 8 for(int i = 0; i < nums.size(); i++) 9 { 10 if(nums[i] < dp[0]) 11 dp[0] = nums[i]; 12 else if(nums[i] > dp.back()) 13 dp.push_back(nums[i]); 14 else 15 { 16 int m = 0, n = dp.size(); 17 while(m < n) 18 { 19 int mid = m + (n-m)/2; 20 if(dp[mid] < nums[i]) 21 m = mid+1; 22 else 23 n = mid; 24 } 25 dp[m] = nums[i]; 26 } 27 } 28 return dp.size(); 29 } 30 };
法三:dp稍微复杂一些的写法但是常规思路可能更好想
dp[i]表示到这个数为止最长字数列 = max(前边所有以比这个数小的数结尾的子序列长度+1, 不以这个数为结尾的最长子序列) Note:dp的初始值为1 因为递增序列的最小长度是这个数字本身
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 vector<int> dp(nums.size(), 1); 5 int res = 0; 6 for (int i = 0; i < nums.size(); ++i) { 7 for (int j = 0; j < i; ++j) { 8 if (nums[i] > nums[j]) { 9 dp[i] = max(dp[i], dp[j] + 1); 10 } 11 } 12 res = max(res, dp[i]); 13 } 14 return res; 15 } 16 };