简体   繁体   English

此方法在数组 (python) 中查找反转次数的时间复杂度是多少?

[英]What's the time complexity of this method to find the number of inversions in an array (python)?

inv=0
for j in range(n):
     inv=inv+ sum((x<arr[j]) for x in arr[j:] )

For every element I am checking the number of elements smaller than it occurring after it in the array.( arr[j : ] )对于每个元素,我正在检查数组中小于它出现的元素的数量。( arr[j : ]

It is O(n 2 ) .它是O(n 2 ) Here is how you can compute this:以下是您可以如何计算:

  • for the 1 st element, you need to compare with the next n-1 elements.第一单元,你需要用接下来的n-1个元素进行比较。

  • for the 2 nd element, you need to compare with the next n-2 elements.对于第二个元素,您需要与接下来的 n-2 个元素进行比较。

    ... ...

  • for the n th element, you need to compare with the next 0 elements.对于第 n元素,您需要与接下来的 0 个元素进行比较。

Therefore, in total you are making (n-1) + (n-2) + ... + 1 + 0 = n(n-1) / 2 comparisons, which is quadratic in n.因此,您总共进行 (n-1) + (n-2) + ... + 1 + 0 = n(n-1) / 2 次比较,这是 n 的二次方。


More efficient approaches do exist.确实存在更有效的方法。 For example, by using a divide and conquer based strategy, you can count them in O(n log(n)) .例如,通过使用基于分而治之的策略,您可以在O(n log(n)) 中计算它们。 See this nice link !看到这个不错的链接

inv=0
for j in range(n):
    inv=inv+ sum((x<arr[j]) for x in arr[j:] )

Let's break this code into three parts让我们把这段代码分成三部分

1: inv = 0 This will take contant time operation sat T1 1: inv = 0这将需要恒定时间操作 sat T1

2: for j in range(n): here we are running a loop for variable n 2: for j in range(n):这里我们正在为变量n运行一个循环

total time required now is T1 + N * f(a) here f(a) is the time taken by the body of loop.现在所需的总时间是T1 + N * f(a)这里f(a)是循环体所用的时间。 For simplicity we can remove constant factor.为简单起见,我们可以删除常数因子。 So complexity is N * f(a)所以复杂度是N * f(a)

Now here comes the tricky part.现在到了棘手的部分。 What is f(a)什么是 f(a)

3: inv = inv + sum((x<arr[j]) for x in arr[j:] ) concentrate on sum((x < arr[j] for x in arr[j:]) sum will add all the values that are below arr[j] in 3: inv = inv + sum((x<arr[j]) for x in arr[j:] )专注于sum((x < arr[j] for x in arr[j:]) sum 将添加所有低于arr[j]的值

loop for x in arr[j:] for x in arr[j:]循环for x in arr[j:]

so you are left with f(a) as N , N - 1 , N - 2 up to N - N所以你留下 f(a) 作为NN - 1N - 2直到N - N

Combining this all together you get N * (N + N - 1 + N - 2 + ... + N - N) which is (N * N - 1) / 2 that is O(N^2)将所有这些结合在一起,你得到N * (N + N - 1 + N - 2 + ... + N - N)(N * N - 1) / 2O(N^2)

Hope you get it.希望你能明白。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM