给定一个无序的整数数组,找到其中最长上升子序列的长度。
解法1.动态规划
时间复杂度O($n^2$)
思路
f[i]
表示以ith字符结尾的最长上升子序列长度
这道题难在状态转移的求解f[i]=max(f[i-1],f[i-2],......)+1
前提条件是 f[j]<f[i] 才能构成上升子序列
1 | int lengthOfLIS(vector<int>& nums) { |
解法2 直接构造最长上升子序列
时间复杂度 $O(nlogn)$
开一个辅助数组 f[i]
表示最长上升子序列长度为i+1
中最小结尾值
eg. [1,2,4] ,[1,2,3]两个子序列长度都为3, 但是第一个子序列结尾值3<4 ,于是 f[2]=3;
这里面的思路背景是 在dp解法中 f[i]=max(f[j]+1) nums[j] 越小 那么对nums[i]限制就越小
两个最长上升子序列长度相同 那么子序列尾部值越小 越有可能构建成更加长的子序列
由于构造的辅助数组一定单调上升,因此可以通过二分查找来做。
1 | int lengthOfLIS(vector<int>& nums) { |
最好是通过一个 toy example 来给给面试官讲这个思路。