对于数组A,B:
A = [a0, a1, ... , an-1]
B = [b1, b2, ..., bn-1]
有多少组i, j使得:
i < j && A[i] < B[j]
A = [a0, a1, ... , an-1]
B = [b1, b2, ..., bn-1]
有多少组i, j使得:
i < j && A[i] < B[j]
1
em70 Aug 17, 2014
A,B数组长度相等吗
|
3
wisatbff Aug 17, 2014
先排序,然后就不用说了吧
|
4
freetg Aug 17, 2014
k=0
for i in xrange(n-1): for j in xrange(i+1, n-1): if A[i] < B[j]: k += 1 print k |
6
yangff Aug 17, 2014 via Android
树状数组
|
8
em70 Aug 17, 2014
遍历肯定可以解决,算法复杂度2^n,主要你希望简化到多少?
|
9
takato Aug 17, 2014 via iPhone
O(nlogn)
|
10
luoluoluo OP |
11
bcxx Aug 17, 2014
@luoluoluo 试试可以将两个数组进行基排(或者其他 O(n) 的排序算法),然后再遍历两个数组,用类似归并排序的方法来逐个比较就可以了。这样就 O(n) 吧
|
12
xjx0524 Aug 17, 2014 两个数组分别排序O(nlog(n))
遍历A数组,对其中每个元素在B中二分,可以知道有多少比他大的 这样时间复杂度O(nlog(n)) |
15
GtDzx Aug 17, 2014 线段树或者树状数组 复杂度O(nlogn)
元素取值范围足够大的话,应该不存在O(n)算法。否则可以通过构造这类问题来O(n)解决n个元素排序问题。(这点我没想太仔细,不过感觉是上可以这样证明复杂度下限的 :P) |
19
xjx0524 Aug 17, 2014
@luoluoluo
我说的那种二分的方法,假设n为B数组元素个数 遍历A数组,拿a[i]在B中二分,找到位置使b[j]<=a[i]且b[j+1]>a[i],那么总结果就加上n-j-1(如果数组索引从0开始) 对A数组中每个元素都这么做时间复杂度O(nlogn) |
20
glasslion Aug 17, 2014
keyword: 逆序数
|
23
shoumu Aug 17, 2014
|
25
joying Aug 17, 2014
时间复杂度O(nlogn),先对两数组排序,后遍历A数组,对B数组进行二分查找,找到刚好比A[i]小的数的下标j,通过下标即可知道比A[i]大的B[j]的数量。
可以再优化,对B数组的二分查找不必从0开始,而是从刚好比A[i]小的B[j]开始。 |
26
aheadlead Aug 17, 2014 via iPhone
记得有个很奇妙的方法可以做到 线性时间复杂度
|
27
xjx0524 Aug 17, 2014
@joying 哥们咱俩思路一样,但其实是错的,题目要求的不是任意i,j使得a[i]<b[j],是要求i < j时 A[i] < B[j],一排序就乱了。。。
|
28
Exin Aug 17, 2014
不太明白你们为什么说排序……
我想角标和本身的值可以看做两个等价的属性, 那么排序前角标是有序的,排序后值是有序的, 那么排序应该是没有意义的。 能解释下吗? |
29
yangff Aug 17, 2014 via Android
不可能做到线性
如果让A=B 那么问题就变成求A的逆序对数 A的逆序对数的已知最优复杂度是O(nlgn) 故原问题复杂度不可能小过O(nlgn) |
31
luoluoluo OP |
32
aheadlead Aug 17, 2014
- - 好像看错了 是不是求逆序对啊...
|
35
tideline Aug 17, 2014
这应该是一个稍作变形的逆序对问题吧,用树状数组写了一下,时间复杂度O(nlogn),代码: http://paste.ubuntu.com/8071502/
这个版本的缺陷在于对数的大小有限制(数组里不能有负数和太大的数),可以离散化改进一下 |