最长递增子序列 python

最长递增子序列
重点是:输出序列而非最大长度!
题目:给定长度arr,设长度为n,输出arr的最大增量子序列。(如果有多个答案,请输出其中字典序最小的
时间复杂度:O(nlogn)

n=int(input())
arr=list(map(int,input().split()))
dp,helper=[1]*n,[arr[0]]
# helper 长度为i的LIS末尾的数 helper才是真的dp 
# dp存放以i结尾的序列长度
import bisect  # 系统二分查找
def mybisect(a,num):   # 自己写的二分查找
    def bi(l,r,num):
        if l==r:
            return l
        mid=(l+r)//2
        if a[mid]>=num:
            r=mid
        elif a[mid]<num:
            l=mid+1
        return bi(l,r,num)
    return bi(0,len(a)-1,num)
for i,a in enumerate(arr[1:],1):  # index,value 从index1开始
    if a>helper[-1]:
        helper.append(a)
        dp[i]=len(helper)
    else:
        # pos=bisect.bisect_left(helper,a) # 找到可替换的值 此时a<=helper[pos] a>helper[pos-1]
        pos=mybisect(helper,a) # 找到可替换的值 此时a<=helper[pos] a>helper[pos-1]
        dp[i]=pos+1  # pos从0开始,dp从1开始
        helper[pos]=a
end,length=helper[-1],len(helper)
index=n-1-arr[::-1].index(end)  # 倒着找,前面的可能不够
res=[]
while index>=0:
    if res==[] or (arr[index]<res[-1] and dp[index]==length):  # 注意not res 等同于 res==[], 而非res==None,会报错~~
        res.append(arr[index])
        length-=1
    if not length:
        break
    index-=1
print(' '.join(map(str,res[::-1])))



全部评论

相关推荐

01-07 07:54
已编辑
门头沟学院 前端工程师
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客企业服务