最长不下降子序列LIS(输出和不输出的区别)

最长不下降子序列LIS

输出结果

时间复杂度 O(n^2)
此时dp数组中记录的 都是从0 到当前位置的最优解,再根据原数组,可以输出合适的子序列(因为结果不唯一)

	int LIS(vector<int>& arr) {
		unsigned short dp[100001];
		memset(dp, 0, sizeof(unsigned short)*arr.size());
		dp[0] = 1;
		unsigned short res = 1;
		for (int i = 1; i < arr.size(); ++i) {
			for (int j = 0; j < i; ++j) {
				if (arr[i] >= arr[j]) {
					dp[i] = max((unsigned short)(dp[j] + 1), dp[i]);
					res = max(dp[i], res);
				}
			}
		}
		return res;
	}

不输出结果

最简单的时间复杂度:O(nlogn)

	int lengthOfLIS(vector<int>& nums) {
		unsigned short res = 1;
		unsigned short dp[100001];
		dp[res] = nums[0];
		for (int i = 1; i < nums.size(); ++i) {
			if (nums[i] >= dp[res]) {
				dp[++res] = nums[i];
			}
			else {
				int l = 1, r = res, pos = 0;
				while (l <= r) {
					int mid = (l + r) >> 1;
					if (dp[mid] <= nums[i]) {
						pos = mid;
						l = mid + 1;
					}
					else {
						r = mid - 1;
					}
				}
				dp[pos + 1] = nums[i];
			}
		}
		return res;
	}
};

再附上简化代码:

	int max_len = 0;
	int min_val[m];
	for (int j = 0; j < arr.size(); ++j) {
		const auto it = upper_bound(min_val, min_val + max_len, arr[j]);
		if (distance(min_val, it) == max_len) ++max_len;
		*it = arr[j];
	}

此时 只能输出长度 不能得到子序列。
这里的min_val数组储存的并不是最大的子序列
比如 :序列 1,3,4,2,3,5,7,4

  • min_val ->{1}
  • min_val ->{1,3}
  • min_val ->{1,3,4}
  • min_val ->{1,2,4}//非子序列
  • min_val ->{1,2,3}
  • min_val ->{1,2,3,5}
  • min_val ->{1,2,3,5,7}
  • min_val ->{1,2,3,4,7} //非子序列

最后只能得到长度为 5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值