问题是: 给定一个2n个整数数组,您的任务是将这些整数分组为n对整数,例如(a1,b1),(a2,b2),...,(an,bn),它们使min(ai, bi)表示从1到n尽可能大的所有i。
解决方案提供为:
public class Solution {
public int arrayPairSum(int[] nums) {
int[] arr = new int[20001];
int lim = 10000;
for (int num: nums)
arr[num + lim]++;
int d = 0, sum = 0;
for (int i = -10000; i <= 10000; i++) {
sum += (arr[i + lim] + 1 - d) / 2 * i;
d = (2 + arr[i + lim] - d) % 2;
}
return sum;
}
}
我认为说时间复杂度为O(n)是不公平的。尽管O(n + K)K = 20001是一个常数,似乎可以省略,但n也小于K。如果是这样,为什么我不能说时间复杂度为O(1)?
答案 0 :(得分:2)
对于所有n,将渐近复杂度测量为n的函数。我们担心n变大时会发生什么。真的,真的很大。
实际上,n总是很小。很好
但是,当您给出算法的复杂性度量时,按照定义,您是在说随着n的增长而发生的事情。并成长。当它这样做时,它将使K相形见。
原来是O(n)。
说明:
问题说明确实是这样的:
n是一个正整数,范围为[1,10000]。
数组中的所有整数都将在[-10000,10000]范围内。
但是请记住,那仅仅是为了解决这个问题!给定硬编码K值的解决方案。正如您所注意到的,此处使用的算法实际上应写为O(n + K)。这个K不是一个恒定因子,可能不应该被丢弃。
但是对于渐近复杂度(Big-O,Big-Theta等),即使具有任意但有限的K,您仍然可以找到常数k和N,使得对于所有n> N,kn>所需的操作数在此算法中,这是Big-O定义。这就是为什么您会看到很多人说O(n)的原因。
希望有帮助。