10 + 9 + 8 + ... + 1 的时间复杂度是多少? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
smallyu
V2EX    程序员

10 + 9 + 8 + ... + 1 的时间复杂度是多少?

  • &nsp;
  •   smallyu 2020-07-16 12:15:34 +08:00 4720 次点击
    这是一个创建于 1918 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有一个两层的循环,如果是

    n = 0 for i in range(10): for j in range(10): n += 1 print(n) // 100 

    复杂度应该是 n^2 吧,那这样呢:

    n = 0 for i in range(10): for j in range(i, 10): n += 1 print(n) // 55 

    相当于 10 + 9 + 8 + ... + 1 = 55,这个复杂度应该怎么描述?

    两个循环还好理解,如果是三层循环呢:

     n = 0 for i in range(10): for j in range(i, 10): for k in range(j, 10): n += 1 print(n) // 220 

    主要是三层循环就想不明白了,求教这怎么理解呢?

    24 条回复    2020-07-16 17:51:39 +08:00
    sivacohan
        2
    sivacohan  
    PRO
       2020-07-16 12:22:38 +08:00 via iPhone   8
    你这三个例子都是 O(1)
    因为,输入与输出无关。

    你重新看一下定义吧,你概念都理解错了。
    ChanKc
        3
    ChanKc  
       2020-07-16 12:23:31 +08:00 via Android
    在我看来都是 O(1)
    Mutoo
        4
    Mutoo  
       2020-07-16 12:33:03 +08:00   1
    大 O 表示法只取与当问题规模 n 趋于无穷大的时候,与 n 相关的最高次幂项。常数和低次项都可以忽略。
    kilasuelika
        5
    kilasuelika  
       2020-07-16 12:34:46 +08:00 via Android
    考虑时间复杂度,循环范围一般是个变量。比如:
    for i in range(n):
    ....

    复杂度为 O(n)。
    for i in range(n):
    for j in range(i,n):
    ...
    复杂度为 O )
    kilasuelika
        6
    kilasuelika  
       2020-07-16 12:36:19 +08:00 via Android
    考虑时间复杂度,循环范围一般是个变量。比如:
    for i in range(n):
    ....

    复杂度为 O(n)。
    for i in range(n):
    for j in range(i,n):
    ...
    复杂度为 O(n^2)。
    putaozhenhaochi
        7
    putaozhenhaochi  
       2020-07-16 12:37:25 +08:00 via Android
    时间复杂度描述的是增长趋势
    polaa
        8
    polaa  
       2020-07-16 12:37:50 +08:00
    都是 O(1) ...
    把 10 换为 n 的话

    第一个 O(n^2)
    第二个 O(n^2) ∑(i = 1~n) ∑ (j = i~n) = ∫∫ = 1/2 n^2
    第三个 同理

    不知道算错没 QAQ
    optional
        9
    optional  
       2020-07-16 12:38:10 +08:00
    中间的 n += 1 被执行了几次就是多少
    octobered
        10
    octobered  
       2020-07-16 12:42:09 +08:00
    都是 O1,都确定次数了
    ps: 这个写成 c,放到 gcc 里开 O3 就直接 print(100)了
    allenhu
        11
    allenhu  
       2020-07-16 12:49:52 +08:00 via Android
    你的运算次数没有受 n 的影响,是常量,所以是 o1
    allenhu
        12
    allenhu  
       2020-07-16 12:54:19 +08:00 via Android
    举例:假设从 1 一直加到 n 求和,你需要加 n 次,此时运算次数与 n 相关了,它是 o ( n )
    necomancer
        13
    necomancer  
       2020-07-16 13:26:38 +08:00
    O(N^2), O(N^3),上面解释很清楚了,如果你还是有困惑的话:

    In [1]: s = 0

    In [2]: for i in range(100):
    ...: for j in range(i, 100):
    ...: s += 1
    ...:

    In [3]: s
    Out[3]: 5050

    In [4]: s = 0

    In [5]: for i in range(1000):
    ...: for j in range(i, 1000):
    ...: s += 1
    ...:

    In [6]: s
    Out[6]: 500500

    In [7]: s/5050
    Out[7]: 99.10891089108911

    In [8]: (1000/100) **2
    Out[8]: 100.0
    whileFalse
        14
    whileFalse  
       2020-07-16 13:46:24 +08:00
    第二个是 O(n^2),第三个是 O(\n^3)。
    你先要理解一个概念:O(n/2)、O(n+100)的正确表述是 O(n)。
    也就是说,以下三个算法的时间复杂度是一样的:
    1. for i in range(n): dosomething(i)
    2. for i in range(n/2): dosomething(i)
    3. for i in range(n+100): dosomething(i)
    时间复杂度取值为整个算法循环次数公式中中成长速度最快的那个部分,成长速度较低的部分被直接删除;系数全部设为 1 。
    对于第二个算法,其循环次数为 n*(n+1)/2=0.5 * n^2 + 0.5 * n 。"0.5 n^2"的成长速度大于“0.5*n”,所以 0.5*n 被删除,剩下"0.5 n^2";然后系数设置为 1,即其时间复杂度为 O(n^2)
    raysonx
        15
    raysonx  
       2020-07-16 14:38:59 +08:00 via iPad   1
    反对 13 楼和 14 楼都答案。题主的代码复杂度均为 O ( 1 )。

    按照循环层数猜测复杂度是典型的民科。楼主可以看一下堆排序算法中建堆的复杂度为什么是 O ( n )。
    w99w
        16
    w99w  
       2020-07-16 16:26:05 +08:00
    O(n)
    w99w
        17
    w99w  
       2020-07-16 16:27:57 +08:00
    另外,楼主你的写法就不太对。
    一般不是 n+=1,而是 n+=i
    1~n 相加整个运算过程需要计算 n 次加法。
    所以是 O(n)
    wellsc
        18
    wellsc  
       2020-07-16 16:28:35 +08:00
    常量 1
    iseki
        19
    iseki  
       2020-07-16 16:29:20 +08:00
    我记得他们讲大 O 符号的时候讲了下θ渐进符号 emmm,取最高次项幂?
    newtype0092
        20
    newtype0092  
       2020-07-16 16:35:58 +08:00
    如果你是想求等差数列的复杂度,
    (1+n)*n/2 = n^2/2 + n/2
    复杂度只看 n^2
    newtype0092
        21
    newtype0092  
       2020-07-16 16:37:56 +08:00
    我也被自己绕昏了,看起来确实是 O(1)啊
    SiliusMo
        22
    SiliusMo  
       2020-07-16 17:48:09 +08:00
    从 1 加到 10 这个代码里都没有 n. 哪里来的 O(n)?
    无论你套几层循环,需要的步骤都是常量, 所以结果是 O(A). A 代表一个常数. 其实也就是 O(1).
    ourFEer
        23
    ourFEer  
       2020-07-16 17:51:33 +08:00
    O(1)
    wnpllrzodiac
        24
    wnpllrzodiac  
       2020-07-16 17:51:39 +08:00 via Android
    复杂度和 指令优化是两个概念。虽然现在编译器智能了,而且机器性能高了,很多东西都不需要人考虑了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     884 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:23 PVG 05:23 LAX 14:23 JFK 17:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86