我最早的思路是反过来遍历,结果总是不对。因为老是觉得动态规划就是列递归,所以一心琢磨着怎样递归,导致一直不对。
正确的思路应该是什么呢?应该是尝试用符号表示其最优的状态和其子状态,然后找出状态之间转移的方法。最后实现这个方法。
最长增长序列的最优状态是什么样子呢?既然是最长,肯定是要容纳尽可能多的元素,怎样容纳尽可能多的元素呢?那就是较小值尽可能小。
那么遍历到的新元素就存在两种情况:
1. 新元素比已知当前 LIS 中的每个元素都要大,那毫无疑问应该加入 LIS。
2. 新元素比当前 LIS 中的某个元素 e 要小,那么则替换哪个元素,以求 LIS 中较小的值尽可能的小。
其实知道第二步的时候,代码就出来了:
int lengthOfLIS(vector<int>& nums) {
list<int> result;
for (const auto& i : nums){
auto loc = std::lower_bound(result.begin(), result.end(), i);
if (loc == result.end()){
result.push_back(i);
}else{
*loc = i;
}
}
return static_cast<int>(result.size());
}