最长递增子序列 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])))



全部评论

相关推荐

02-26 15:38
门头沟学院 Java
投PCG后端开发被WXG测开捞,上来先写2道算法1、无重复的最长子串2、嵌套信封a出来了,但是求最长递增子序列,时间复杂度O(n^2),给提示优化,没答出来,贪心+二分3、HashMap和HashSet的区别,线程安全吗?4、为什么线程不安全,实现线程安全用哪个集合?接下来结合项目问八股5、token是干嘛的?设置的过期时间?如何续期?网络抖动没续期上怎么办?6、提了个双token方案,解释双token?没解释清为什么要用refreshtoken和acesstoken,以及区别,用一个不就行?7、Redis用的数据类型,持久化方式?8、Redis变慢了怎么定位,怎么优化?9、Redis确实要存储很多数据怎么办?用的什么集群?怎么同步数据?10、怎么用redis实现一个限流算法?11、缓存三剑客在现实当中什么场景会出现?举例12、怎么解决,布隆过滤器能不能删除元素?13、为什么用MQ?库存上游服务是谁?为什么不能直接DB获取?14、多少用户量并发访问吞吐量会有区别?RabbitMQ承受量级?想要更高怎么办?15、和kafka的区别?16、多消费者消费消息的顺序性RabbitMQ可以保证吗?怎么实现消费顺序性?17、考虑消费失败情况吗,消费失败怎么办?具体用到几个队列?处理逻辑?18、如何处理多线程情况,有哪些方法?19、Synchronized和ReentrantLock的区别?喜欢用哪个?20、自旋锁是什么?Synchronized属于自旋锁吗?21、数据库查询比较慢怎么办?如果不是索引原因呢?22、索引的底层数据结构?可以用Hash表吗?23、什么时候用多进程?什么时候用多线程?还是太菜了😭很多回答模棱两可
查看23道真题和解析
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客企业服务