import bisect

class Solution:
    def LIS(self , arr ):
        # write code here
        arrLen = len(arr)
        if arrLen < 2:
            return arr

        ansArr = [arr[0]]  # 记录某个数字结尾时最长的最长递增子序列,初始化第一个数字
        maxLen = [1]  # 下标i时,最长的递增子序列长度,初始化1

        for a in arr[1:]:
            if a > ansArr[-1]:  # 当前数字大于ansArr最后一个数字,子数组保持递增
                ansArr.append(a)
                maxLen.append(len(ansArr))
            # 当前数字小于等于ansArr最后一个数字,二分查找ansArr中第一个比当前数字大的下标pos
            # 替换ansArr中下标pos的数字为当前数字,更新maxLen,记录当前最长递增子序列长度为:pos + 1(下标+1)
            else:
                pos = bisect.bisect_left(ansArr, a)
                ansArr[pos] = a
                maxLen.append(pos + 1)
        # 找到的ansArr不一定是最终结果,[2,1,5,3,6,4,8,9,7] - > [1, 3, 4, 7, 9] (不是最终结果)
        # [1, 1, 2, 2, 3, 3, 4, 5, 4] 从后往前遍历maxLen,依次找到等于len(arrLen)对应的 arr[i] 
        ansLen = len(ansArr)
        for i in range(arrLen - 1, -1, -1):
            if maxLen[i] == ansLen:
                ansArr[ansLen - 1] = arr[i]
                ansLen -= 1
        return ansArr

arr = [2,1,5,3,6,4,8,9,7]
# arr = [1,2,8,6,4]
ans = Solution().LIS(arr)
print(ans)