时间复杂

时间:2011-04-07 18:41:19

标签: algorithm time-complexity

问题在于找到数组中的多数元素。 我理解这个算法是如何工作的,但是我不知道为什么它有O(nlogn)作为时间复杂度.....


一个。两者都返回\没有多数。“然后阵列的一半都没有多数 元素,组合数组不能有多数元素。因此, 呼叫返回\没有多数。“

湾右边是多数,左边不是。唯一可能的多数 这个级别是在右半部分形成多数的价值,因此, 只需比较组合数组中的每个元素并计算数量 与此值相等的元素。如果它是多数元素则返回 那个元素,否则返回\ no most。“

℃。与上面相同,但左边返回多数,右边返回 \没有多数。“

d。两个子调用都返回多数元素。计算元素数量相等 两个候选人的多数元素。如果其中一个是多数元素 在组合数组中,然后返回它。否则,返回\没有多数。“ 顶级只返回多数元素或没有多数元素 以同样的方式存在。

因此,T(1)= 0且T(n)= 2T(n / 2)+ 2n = O(nlogn)


我想,

每次递归都会将多数元素与整个数组进行比较,后者需要2n。

T(n) = 2T(n/2) + 2n = 2(2T(n/4) + 2n) + 
      2n = ..... = 2^kT(n/2^k) + 2n + 4n + 8n........ 2^kn = O(n^2)

3 个答案:

答案 0 :(得分:1)

T(n)= 2T(n / 2)+ 2n

问题是n要达到1需要多少次迭代。

我们在每次迭代中除以2得到一个系列:n,n / 2,n / 4,n / 8 ...... n /(n ^ k)

所以,让我们找到 k ,这将把我们带到1(最后一次迭代):

n /(2 ^ k)= 1 .. n = 2 ^ k ... k = log(n)

所以我们得到了 log(n)迭代。

现在,在每次迭代中,我们进行2n次操作(因为我们每次将n除以2),但在值得的情况下,我们可以说2n。

总的来说,我们通过 O(n)操作获得log(n)次迭代: nlog(n)

答案 1 :(得分:0)

我不确定我是否理解,但你不能只创建一个哈希映射,遍历数组,在每一步递增hash[value],然后对哈希映射(xlogx时间复杂度)进行排序并比较前两个元素?这将花费您O(n) + O(mlogm) + 2 = O(n + mlogm),其中n为数组大小,m为向量中不同元素的数量。

我错了吗?或者......?

答案 2 :(得分:0)

当你以递归方式执行此操作时,将每个级别的数组拆分为两个,为每一个级别调用一次,然后进行其中一个测试a-d。测试a不需要循环,其他测试需要循环遍历整个阵列。通过平均值,您将遍历递归中每个级别的数组的(0 + 1 + 1 + 1)/ 4 = 3/4。

递归中的级别数基于数组的大小。当您将数组拆分为每个级别的一半时,级别数将为log2(n)。

因此,总工作量为(n * 3/4)* log2(n)。由于常量与时间复杂度无关,并且所有对数都相同,因此复杂度为O(n * log n)。

编辑:

如果有人想知道算法,这里是C#实现。 :)

private int? FindMajority(int[] arr, int start, int len) {
  if (len == 1) return arr[start];
  int len1 = len / 2, len2 = len - len1;
  int? m1 = FindMajority(arr, start, len1);
  int? m2 = FindMajority(arr, start + len1, len2);
  int cnt1 = m1.HasValue ? arr.Skip(start).Take(len).Count(n => n == m1.Value) : 0;
  if (cnt1 * 2 >= len) return m1;
  int cnt2 = m2.HasValue ? arr.Skip(start).Take(len).Count(n => n == m2.Value) : 0;
  if (cnt2 * 2 >= len) return m2;
  return null;
}