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

为何嵌套循环实现的LeetCode两数之和比单循环版本运行更快?

两数之和解法性能疑惑:嵌套逻辑为何比带列表修改的单循环更快?

你提到测试LeetCode两数之和时,出现了反直觉的结果:方法1耗时约344ms,方法2耗时682ms,你原本认为嵌套循环性能远不如单循环。下面拆解具体原因:

先澄清:两种方法的实际时间复杂度都是O(n²),但操作成本天差地别

不要被“单循环/嵌套循环”的表象误导,得看代码内部的具体操作:

方法1的实际执行逻辑

# Approach - 1
for index1, num1 in enumerate(nums):           
        num2 = target - num1
        if num2 in nums[index1 + 1:]:
            if nums.index(num2) != index1:
                return [index1, nums.index(num2)]
            else:
                return [index1, nums[index1 + 1:].index(num2) + index1 + 1]
  • 表面是单循环,但内部的num2 in nums[index1 + 1:]和nums.index(num2)都是线性遍历操作(O(n)复杂度),所以整体是O(n²),和嵌套循环等价。
  • 但这些操作都是只读遍历,不需要修改列表结构,Python对这类操作的优化很到位,常数时间开销极低。

方法2的实际执行逻辑

# Approach - 2
for i in range(len(nums)):
        var = target - nums[i]
        a = nums.pop(i)
        try:
            index2 = nums.index(var) + 1
        except:
            nums.insert(i, a)
            continue
        return [i, index2]
  • 同样是O(n²)复杂度,但核心问题出在pop(i)和insert(i, a)这两个操作:
    Python的列表是动态数组,执行pop(0)或中间位置的pop/insert时,需要把后面所有元素向前/向后移动一位,这是O(n)级别的修改操作,常数时间开销远大于单纯的遍历。
  • 哪怕目标数在列表开头,方法2执行pop(0)时,也要移动整个列表的元素,这一步的开销就已经超过方法1的所有操作了。

目标数在列表开头的场景分析

  • 方法1:当index1=0时,num2 in nums[1:]只需遍历到nums[1]就找到目标,nums.index(num2)直接返回1,整个过程只有几次简单的元素查找,几乎无额外开销。
  • 方法2:当i=0时,pop(0)需要移动所有元素,哪怕之后的index(var)很快找到结果,pop操作的成本已经远远超过方法1。

补充:如果目标数在列表末尾

  • 方法1需要遍历到最后一个元素,内部的遍历操作虽多,但依然只是只读访问,开销可控。
  • 方法2在遍历到末尾前,每一次循环都要执行pop和insert(因为没找到目标),每次都是O(n)的修改操作,累积起来的开销会呈指数级增长。

总结

你看到的反直觉结果,本质是误解了“循环结构”和“实际操作成本”的关系——方法2的“单循环”包含大量高开销的列表修改,而方法1的“嵌套逻辑”只是单纯的只读遍历,实际执行效率自然更高。

内容的提问来源于stack exchange,提问作者A typical nerd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:23:21