0
点赞
收藏
分享

微信扫一扫

leetcode-300. 最长递增子序列

快乐小码农 2022-01-11 阅读 31

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
		int len = nums.size();
		if(len <= 0)
			return 0;
		vector<int> dp(2500, 1);
		// dp[i]的意思是:包含nums[i]的前面i+1个结点的最长子序列
		dp[0] = 1;
        int maxlen = 1;
		for(int i = 1; i < len; i++) {
			for(int j = 0; j < i; j++) {
				if(nums[i] > nums[j]) {
					dp[i] = max(dp[i], dp[j] + 1);
                    if(dp[i] > maxlen)
                        maxlen = dp[i];
				}
			}
		}
		
		return maxlen;
    }
};

越小的数字越要往前放,让坡度越缓慢

复杂度:时间复杂度O(nlogn)
class Solution {
public:
int lengthOfLIS(vector& nums) {
//让坡度上升尽可能缓慢
int len = nums.size();
if(len <=0) return 0;
vector v;

	v.push_back(nums[0]);
	for(int i = 1; i < len; i++) {
		if(nums[i] > v[v.size()-1]) {
			v.push_back(nums[i]);
		} else if (nums[i] < v[v.size()-1]) {
			//二分查找,找到比该数字大或者相等的第一个位置,然后放进去
			int left = 0;
			int right = v.size()-1;
			int mid;
			while(left < right) {
				mid = (left + right)/2;
				if(v[mid] == nums[i]) {
					left = mid;
					break;
				} else if (v[mid] > nums[i]) {
					right = mid;
				} else {
					left = mid + 1;
				}
			}
			
			v[left] = nums[i];
		}
	}
	
	return v.size();
}

};

0 1 2 3 4 5
0 1 0 3 2 3
i = 0:
v = 0
i = 1
v = 0 1
i = 2

le = 0 ri = 1 mid = 0
v[0] == 0
le = 0
v = 0 1

i = 3
v = 0 1 3

i = 4 放2
le = 0 ri = 2 mid = 1
v[1] = 1 < 2
le = 2 ri = 2
v = 0 1 2

i = 5
v = 0 1 2 3

举报

相关推荐

0 条评论