LeetCode673 最长递增子序列的个数

LeetCode673 最长递增子序列的个数

贪心 + 前缀和 + 二分查找

\(q[i][]\) 数组表示所有能成为长度为 \(i\) 的最长上升子序列的末尾元素的值

\(cnt[i][j]\) 记录以 \(q[i][j]\) 为结尾的最长上升子序列的个数

参考

class Solution:
    def findNumberOfLIS(self, nums: List[int]) -> int:

        q, cnt = [], []

        for num in nums:
            idx = self.bisearch(len(q), lambda i:q[i][-1] >= num)
            if idx > 0:
                k = self.bisearch(len(q[idx - 1]), lambda i:q[idx - 1][i] < num)
                c = cnt[idx - 1][-1] - cnt[idx - 1][k]
            else: c = 1

            if idx == len(q):
                q.append([num])
                cnt.append([0, c])
            else:
                q[idx].append(num)
                cnt[idx].append(cnt[idx][-1] + c)
            
        return cnt[-1][-1]

    def bisearch(self, n, f):

        l, r = 0, n
        while l < r:
            mid = (l + r) // 2
            if f(mid): r = mid
            else: l = mid + 1
        return l

posted on 2022-07-03 15:54  solvit  阅读(24)  评论(0编辑  收藏  举报

导航