以下代码片段的时间复杂度是多少?

Posted

技术标签:

【中文标题】以下代码片段的时间复杂度是多少?【英文标题】:What is the time complexity of the following code snippet? 【发布时间】:2017-07-06 21:22:33 【问题描述】:

我编写了以下代码 sn-p 来查找范围摘要,即,当给定一个没有任何重复的排序整数数组时,它返回摘要为:

/* IP: [0,1,2,4,5,7]
 * OP: ["0->2","4->5","7"]
 */

class Solution 
public:
    vector<string> summaryRanges(vector<int>& nums) 
        vector<string> res;

        if(nums.empty())
            return res;

        for(int i=0; i<nums.size(); i++) 
            int lowerRange=nums[i];

            while(((i+1)<nums.size()) && (nums[i+1]-nums[i]==1))
                i++;

            int higherRange=nums[i];

            if(lowerRange!=higherRange) 
                string str=to_string(lowerRange)+"->"+to_string(higherRange);
                res.push_back(str);
             else
                res.push_back(to_string(lowerRange));
        

        return res;
    
;

我想知道上面代码 sn-p 的时间复杂度。在我看来,我正在为数组中的每个元素(使用外部 for 循环)执行一些“任务”(执行内部 while 循环)。因此,在我看来,在最坏的情况下,复杂度应该是 O(n^2)。另一方面,我很怀疑,因为我在内部 while 循环中执行 i++,因此,我不会使用外部 for 循环对 所有 元素执行“任务”。由于这个增量,我在整个代码中只访问所有元素一次。因此,这应该使复杂度为 O(n)。有人可以确认复杂度是 O(n^2) 还是 O(n)?

【问题讨论】:

我认为你是对的。内循环使外循环的索引前进,所以它真的就像一个循环。 @Ramesh 我有点太快发表评论了。线性是正确的答案:) @Barmar,但在最坏的情况下,外部 for 循环将为每个元素执行内部 while 循环(可能访问所有元素)。那么,那不就是O(n^2)吗? Re,“我正在为数组中的每个元素执行一些‘任务’(执行内部 while 循环)。”不,因为内部循环和外部循环都增加了同一个变量。您的函数只从头到尾扫描一次数组。如果你添加一些状态变量,它可以被重写为一个循环。 内循环访问的任何元素都会被外循环跳过。他们一起只需访问所有元素一次。 【参考方案1】:

由于内循环与外循环推进相同的迭代变量,因此内循环访问的任何元素都会被外循环跳过。他们一起只访问每个元素一次。这样就变成了O(n)

就时间复杂度而言,它就像一个带有if 语句的循环:

for (i = 0; i < nums.size(); i++) 
    if ((i+1)<nums.size()) && (nums[i+1]-nums[i]==1)) 
        //
     else 
        //
    

以这种方式编写它需要不同的逻辑来确定何时更新lowerRangehigherRange

【讨论】:

抱歉,我不得不接受@T33C 的回答,因为它看起来更详细。我希望我能同时接受。【参考方案2】:

你在你的内部循环中前进,因此它以 O(n) 的时间复杂度运行。

【讨论】:

以上是关于以下代码片段的时间复杂度是多少?的主要内容,如果未能解决你的问题,请参考以下文章

以下代码的时间复杂度是多少?

以下代码的时间复杂度是多少,如何将其更改为线性或对数时间复杂度?

以下递归算法的时间复杂度是多少?

关于代码片段的时间复杂度

该算法的比特成本时间复杂度是多少(Java 示例)?

这个特定代码的时间复杂度是多少?