【发布时间】:2018-03-11 01:26:20
【问题描述】:
我正在解决LeetCode.com上的一个问题:
给定一个正整数向量
nums,计算并打印子数组中所有元素的乘积小于 k 的(连续)子数组的数量。
代码(我在大量在线帮助下编写的)如下:
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(nums.empty() || k<=1) return 0;
int counter=0, left=0, currProd=1;
for(int i=0; i<nums.size(); i++) {
currProd*=nums[i];
while(left<nums.size() && currProd>=k)
currProd/=nums[left++];
counter+=i-left+1;
}
return counter;
}
};
虽然我了解发生了什么,但我不明白时间复杂度是如何被称为O(n) 而不是O(n^2)。恕我直言,i 和 left 都会增加,导致在最坏的情况下访问 nums 的每个元素两次 - 一次是通过归纳变量 i,然后是 left。
那么,O(n) 的时间复杂度如何?
【问题讨论】:
-
如果你在一个循环中有一个循环,你通常会遇到 O(n^2) 的情况。
-
@tadman,然而,据说时间复杂度是 O(n)。
-
理论上这可能是正确的,但我认为您的代码不符合该标准。您可能需要另一种方法。对于 O(n),您需要使用单循环执行一次通过方法。
-
我认为要真正做到O(n),您需要摆脱内部
while,所以这是一个简单的线性扫描。您可能需要使用一些巧妙的技巧来消除这种情况。 -
我认为如果它符合 O(n) 条件,那是因为
left在循环内永远不会重置为零,因此“内循环”永远不会迭代超过mums.size()次不管外循环迭代多少次。
标签: c++ algorithm time-complexity