classSolution:deflengthOfLIS(self,nums: List[int]) ->int: n =len(nums)if n ==0:return0 dp = [1] * n ans =1for i inrange(n):for j inrange(i):if nums[i]> nums[j]: dp[i]=max(dp[i], dp[j] +1) ans =max(ans, dp[i])return ans
classSolution:deffindMinArrowShots(self,intervals: List[List[int]]) ->int: n =len(intervals)if n ==0:return0 dp = [1] * n ans =1 intervals.sort(key=lambdaa: a[0])for i inrange(len(intervals)):for j inrange(i -1, -1, -1):if intervals[i][0] > intervals[j][1]: dp[i]=max(dp[i], dp[j] +1)break# 由于是按照开始时间排序的, 因此可以剪枝returnmax(dp)
复杂度分析
时间复杂度:$O(N ^ 2)$
空间复杂度:$O(N)$
优化
大家想看效率高的,其实也不难。 LIS 也可以用 贪心 + 二分 达到不错的效率。代码如下:
代码文字版如下:
classSolution:deflengthOfLIS(self,A: List[int]) ->int: d = []for a in A: i = bisect.bisect_left(d, a)if i <len(d): d[i]= aelifnot d or d[-1]< a: d.append(a)returnlen(d)
如果求最长不递减子序列呢?
我们只需要将最左插入改为最右插入即可。代码:
classSolution:deflengthOfLIS(self,A: List[int]) ->int: d = []for a in A:# 这里改为最右 i = bisect.bisect(d, a)if i <len(d): d[i]= a# 这里改为小于等号elifnot d or d[-1]<= a: d.append(a)returnlen(d)
最左插入和最右插入分不清的可以看看我的二分专题。
也可以这么写,更简单一点:
defLIS(A): d = []for a in A:# 如果求要严格递增就改为最左插入 bisect_left 即可 i = bisect.bisect(d, a)if i ==len(d): d.append(a)elif d[i]!= a: d[i]= areturnlen(d)
classSolution:defpileBox(self,box: List[List[int]]) ->int: box =sorted(box, key=sorted) n =len(box) dp = [0if i ==0else box[i -1][2] for i inrange(n +1)] ans =max(dp)for i inrange(1, n +1):for j inrange(i +1, n +1):if box[j -1][0] > box[i -1][0] and box[j -1][1] > box[i -1][1] and box[j -1][2] > box[i -1][2]: dp[j]=max(dp[j], dp[i] + box[j -1][2]) ans =max(ans , dp[j])return ans
classSolution:defminOperations(self,target: List[int],A: List[int]) ->int:defLIS(A): d = []for a in A: i = bisect.bisect_left(d, a)if d and i <len(d): d[i]= aelse: d.append(a)returnlen(d) B = [] target ={ t:i for i, t inenumerate(target)}for a in A:if a in target: B.append(target[a])returnlen(target)-LIS(B)
classSolution:defsolve(self,nums): n =len(nums) ans =1defLIS(A): d = []for a in A: i = bisect.bisect_left(d,a)if i ==len(d): d.append(a)else: d[i]= areturnlen(d) nums += numsfor i inrange(n): ans =max(ans , LIS(nums[i:i+n]))return ans