时间复杂度

发布于 2024-10-30 18:22:44 字数 644 浏览 2 评论 0原文

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


......两者都返回 \no 大多数。”那么数组的一半都没有多数 元素,并且组合数组不能有多数元素。所以, 调用返回\没有多数。”

b. 右侧是多数,左侧不是。唯一可能的多数 这个水平是右半部分占多数的值,因此, 只需比较组合数组中的每个元素并计算其数量 等于该值的元素。如果是多数元素则返回 该元素,否则返回\无多数。”

c. 与上面相同,但左侧返回多数,右侧返回 \no 大多数。”

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)

The Problem is finding majority elements in an array.
I understand how this algorithm works, but i don't know why this has O(nlogn) as a time complexity.....


a. Both return \no majority." Then neither half of the array has a majority
element, and the combined array cannot have a majority element. Therefore,
the call returns \no majority."

b. The right side is a majority, and the left isn't. The only possible majority for
this level is with the value that formed a majority on the right half, therefore,
just compare every element in the combined array and count the number of
elements that are equal to this value. If it is a majority element then return
that element, else return \no majority."

c. Same as above, but with the left returning a majority, and the right returning
\no majority."

d. Both sub-calls return a majority element. Count the number of elements equal
to both of the candidates for majority element. If either is a majority element
in the combined array, then return it. Otherwise, return \no majority."
The top level simply returns either a majority element or that no majority element
exists in the same way.

Therefore, T(1) = 0 and T(n) = 2T(n/2) + 2n = O(nlogn)


I think,

Every recursion it compares the majority element to whole array which takes 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无畏 2024-11-06 18:22:44

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)

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

The question is how many iterations does it take for n to get to 1.

We divide by 2 in each iteration so we get a series: n , n/2 , n/4 , n/8 ... n/(n^k)

So, let's find k that will bring us to 1 (last iteration):

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

So we got log(n) iterations.

Now, in each iteration we do 2n operations (less because we divide n by 2 each time) but in worth case scenario lets say 2n.

So in total, we got log(n) iterations with O(n) operations: nlog(n)

贪了杯 2024-11-06 18:22:44

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

我这里是不是搞错了?或者 ...?

I'm not sure if I understand, but couldn't you just create a hash map, walk over the array, incrementing hash[value] at every step, then sort the hash map (xlogx time complexity) and compare the top two elements? This would cost you O(n) + O(mlogm) + 2 = O(n + mlogm), with n the size of the array and m the amount of different elements in the vector.

Am I mistaken here? Or ...?

尴尬癌患者 2024-11-06 18:22:44

当您递归地执行此操作时,您将每个级别的数组分成两部分,对每一半进行调用,然后进行其中一个测试 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;
}

When you do this recursively, you split the array in two for each level, make a call for each half, then makes one of the tests a - d. The test a requires no looping, the other tests requires looping through the entire array. By average you will loop through (0 + 1 + 1 + 1) / 4 = 3 / 4 of the array for each level in the recursion.

The number of levels in the recursion is based on the size of the array. As you split the array in half each level, the number of levels will be log2(n).

So, the total work is (n * 3/4) * log2(n). As constants are irrelevant to the time complexity, and all logarithms are the same, the complexity is O(n * log n).

Edit:

If someone is wondering about the algorithm, here's a C# implementation. :)

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;
}
江城子 2024-11-06 18:22:44

这个人有很多关于递归关系的视频,以及可以用来解决它们的不同技术:
https://www.youtube.com/watch?v=TEzbkIggJfo&list=PLj68PAxAKGoyyBwi6qrfcsqE_4trSO1yL

基本上对于这个问题我会使用主定理:
https://youtu.be/i5kTZof1LRY

T(1) = 0 and T(n) = 2T(n/2) + 2n 
Master Theorem ==> AT(n/B) + 2n^D, so in this case A=2, B=3, D=1

所以根据主定理,这是 O(nlogn)

你也可以使用另一种方法来解决这个问题(如下),只是需要更多时间:
https://youtu.be/TEzbkIggJfo?list=PLj68PAxAKGoyyBwi6qrfcsqE_4trSO1yL

希望这对您有帮助!

This guy has a lot of videos on recurrence relation, and the different techniques you can use to solve them:
https://www.youtube.com/watch?v=TEzbkIggJfo&list=PLj68PAxAKGoyyBwi6qrfcsqE_4trSO1yL

Basically for this problem I would use the Master Theorem:
https://youtu.be/i5kTZof1LRY

T(1) = 0 and T(n) = 2T(n/2) + 2n 
Master Theorem ==> AT(n/B) + 2n^D, so in this case A=2, B=3, D=1

So according to the Master Theorem this is O(nlogn)

You can also use another method to solve this (below) it would just take a little bit more time:
https://youtu.be/TEzbkIggJfo?list=PLj68PAxAKGoyyBwi6qrfcsqE_4trSO1yL

I hope this helps you out !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文