You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求高效最长递增子序列(LIS)算法的技术问询

最长递增子序列(LIS)的O(n log n)高效解法

针对大规模数组的LIS求解需求,贪心+二分查找的组合算法可以将时间复杂度优化到O(n log n),比你提到的O(n²)动态规划解法效率提升显著,适合处理大数据量场景。

核心算法原理

维护一个tails数组,其中tails[i]表示长度为i+1的最长递增子序列的最小末尾元素。遍历原数组时,对每个元素执行以下操作:

  • 若当前元素大于tails的最后一个元素,直接追加到tails末尾,意味着LIS的长度增加1;
  • 若当前元素小于等于tails的最后一个元素,用二分查找找到tails中第一个大于等于当前元素的位置,替换该位置的元素为当前元素。这一步的意义是:保留相同长度子序列的最小末尾值,为后续更长子序列的形成提供更大可能性。

最终tails数组的长度就是LIS的长度。如果需要还原具体的子序列,还需要额外记录索引信息。

代码实现(Python)

def length_of_lis(nums):
    tails = []
    for num in nums:
        left, right = 0, len(tails)
        # 二分查找第一个 >= num 的位置
        while left < right:
            mid = (left + right) // 2
            if tails[mid] < num:
                left = mid + 1
            else:
                right = mid
        if left == len(tails):
            tails.append(num)
        else:
            tails[left] = num
    return len(tails)

还原具体LIS的扩展

如果需要得到实际的子序列而非仅长度,需要额外维护两个辅助数组:

  1. prev_indices:记录原数组中每个元素在LIS中的前驱元素索引;
  2. tails_indices:记录tails数组中每个元素对应的原数组索引。

通过这两个数组,可从tails的最后一个元素对应的原数组索引开始,倒推得到完整的LIS。

优化思路参考资源

  • 《算法导论》中动态规划与贪心策略章节,详细讲解了此类贪心+二分优化的底层逻辑;
  • 《算法竞赛入门经典》包含LIS优化的具体案例与变种问题分析;
  • LeetCode第300题(最长递增子序列)的官方题解及社区讨论,涵盖不同优化思路的复杂度对比与实现细节。

内容的提问来源于stack exchange,提问作者Navodya Vidumini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:42:38