LeetCode 300. 最长递增子序列(附带打印字典序最小的序列,动态规划,贪心+二分)

2020年9月17日 周四 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】本文目录1. DP2. 贪心 + 二分查找参考文献1. DPDP法关键在于如何定义状态,由于一个子序列一定会以一个数结尾,于是将状态定义成:dp[i] 表示以 nums[i] 结尾的「上升子序列」的长度。注意:这个定义中 nums[i] 必须被选取,且必须是这个子序列的最后一个元素。class Solution {public: int lengthOfLIS(vector<int>& num
摘要由CSDN通过智能技术生成

2020年9月17日 周四 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】



https://leetcode-cn.com/problems/longest-increasing-subsequence/
在这里插入图片描述

1. DP(附带打印字典序最小的序列)

DP法关键在于如何定义状态,由于一个子序列一定会以一个数结尾,于是将状态定义成:dp[i] 表示以 nums[i] 结尾的「上升子序列」的长度。注意:这个定义中 nums[i] 必须被选取,且必须是这个子序列的最后一个元素。

至于打印字典序最小的序列,只需要从后往前找,具有相同长度的,第一次找到的那个数值最小的,可以用反证法证明,如果是大的话,那么肯定不是相同长度了。

class Solution {
   
public:
	int lengthOfLIS(vector<int>& nums) {
   
		vector<int> dp(nums.size(), 1);
		int maxn = 0, n = nums.size();
		for (int i = 1; i < n; ++i) {
   
			//找到满足 j < i,nums[j] < nums[i],的最大dp[j]进行转移
			int res = 0;
			for (int j = 0; j < i; ++j) {
   
				if (nums[i] > nums[j]) {
   
					res = max(res, dp[j]);
				}
			}
			dp[i] = res + 1;//加上nums[i]
			maxn = max(maxn, dp[i]); //找到最大长度
		}

		// 下面代码的功能:找字典序最小的 最长递增子序列
		// 从后往前找,相同长度的,第一次找到的那个肯定是字典序小的
		// 可以用反证法,如果大的话,那么肯定不是相同长度了
		vector<int> ans(maxn)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值