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)