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)