题解 | #最长上升子序列(三)#

最长上升子序列(三)

http://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481

思路:
先求最长递增子序列长度,再根据长度求字典序最小序列
声明dp[i]: 数组以arr[i]结尾的最长递增序列 对于dp[i], 遍历 arr[1]-arr[i-1], 跟arr[i]比较并取最大值。 即 a[i]>=a[j]: dp[i] = max(dp[i], dp[j]+1); 1<=j<i 其复杂度为O(n^2)

优化:为了避免dp[i]每次都进行比较,用一个数组minele_res来保存之前的递增子序列,确保arr[i]只需要与该数组的最后一个数比较即可得出最长长度,并更新这个数组,利用空间换取时间
minele_res数组每次有最优的子序列时,用二分法找到位置并更新,具体如代码

class Solution:
    def BinSearch(self, arr, target):
        arr_len = len(arr)
        l, r = 0, arr_len-1
        while l < r:
            mid = int(l + (r - l) / 2)
            if arr[mid] > target:
                r = mid
            else:
                l = mid + 1
        return r

  
    def LIS(self, arr):
        dp = [0] * (len(arr))
        dp[0] = 1
        minele_res = [arr[0]]  # 需要多一个数组来存放长度为i时,对应最小的元素
        for i in range(1, len(arr)):
            if arr[i] > minele_res[-1]:
                minele_res.append(arr[i])
                dp[i] = len(minele_res)
            else:
                pos = self.BinSearch(minele_res, arr[i])
                minele_res[pos] = arr[i]
                dp[i] = pos + 1  # 这里的dp值为找到的pos+1
        length = len(minele_res)
        for i in range(len(arr) - 1, -1, -1):
            if dp[i] == length:
                minele_res[length - 1] = arr[i]
                length -= 1
                
        return minele_res
全部评论

相关推荐

ResourceUt...:楼主有自己的垃圾箱,公司也有自己的人才库
点赞 评论 收藏
分享
我只是一个小白菜:我还用不惯m4,也是山猪吃不了细糠了
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务