码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 300. Longest Increasing Subsequence

时间:2018-10-05 23:28:00      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:查找   ==   lse   最长上升子序列   detail   targe   public   规划   注意   

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

Note:

  • 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.

Follow up: Could you improve it to O(n log n) time complexity?

 

非常经典的一道动态规划题目,常用解法有两个

1、暴力搜索

时间复杂度O(N^2),空间复杂度O(N),f[i]表示以num[i]结尾的上升子序列的长度,外层循环遍历整个序列,复杂度O(n),内层循环则从第一个数遍历到外层循环的数字(不含)为止,转移方程为f[i] = max(f[i],f[j]+1)代码如下:

 1 class Solution {
 2 public:
 3     int lengthOfLIS(vector<int>& nums) {
 4         if (nums.size() == 0)
 5             return 0;
 6         vector<int> v;
 7         int len = 1;
 8         for (int i = 0; i < nums.size(); i++)
 9         {
10             v.push_back(1);
11             for (int j = 0; j < i; j++)
12                 if (nums[j] < nums[i])
13                     v[i] = max(v[i], v[j]+1);
14             if (v[i] > len)
15                 len = v[i];
16                     
17         }
18         return len;
19     }
20 };

2、二分搜索

时间复杂度O(N*logN),空间复杂度O(N),我们可以用一个数组,来记录当前已经形成的递增子序列,该数组一定是单调不减的,我们所希望的是末尾的数字尽量小,这样才会使得更多的数字有机会加入进来。外层循环需要遍历整个序列,内层循环则利用有序性进行二分查找,找到该数字在我们定义的数组中的位置,然后更新,最终返回该数组的长度即可,但是这么做要注意我们只保证长度是正确的,不保证该数组是一个最长上升子序列。

代码如下:

 1 class Solution {
 2 public:
 3     int lengthOfLIS(vector<int>& nums) {
 4         if (nums.size() == 0)
 5             return 0;
 6         vector<int> res;
 7         res.push_back(nums[0]);
 8         for (int i = 0; i < nums.size(); i++)
 9         {
10             int left = 0, right = res.size()-1;
11             if (nums[i] > res.back())
12                 res.push_back(nums[i]);
13             else
14             {
15                 while (left < right)
16                 {
17                     int mid = (left + right) / 2;
18                     if (res[mid] < nums[i])
19                         left = mid + 1;
20                     else
21                         right = mid;
22                 }
23                 res[right] = nums[i];
24             }
25         }
26         return res.size();
27     }
28 };

 易错点:6,7行,可以利用c++11新特性写成 res{nums[0]},但是千万别错写成res(nums[0])

 

参考链接:

https://www.cnblogs.com/lsgxeva/p/7787245.html

http://www.cnblogs.com/grandyang/p/4938187.html

https://www.cnblogs.com/GodA/p/5180560.html

https://blog.csdn.net/George__Yu/article/details/75896330

 

LeetCode 300. Longest Increasing Subsequence

标签:查找   ==   lse   最长上升子序列   detail   targe   public   规划   注意   

原文地址:https://www.cnblogs.com/dapeng-bupt/p/9746259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!