我遇到了一个有趣的算法问题:
给定一个整数数组,找出该数组中的无序对数量,例如对于{1, 3, 2},答案为1,因为{3, 2}是无序的;对于数组{3, 2, 1},答案为3,因为{3, 2},{3, 1},{2, 1}都是无序的。
显然,这个问题可以通过O(n^2)的暴力解法或枚举所有可能的对并消除那些无效对来解决。
我的问题是,是否有更好的解决方案,因为它看起来像是一个动态规划问题。提供代码片段会很有帮助。
我遇到了一个有趣的算法问题:
给定一个整数数组,找出该数组中的无序对数量,例如对于{1, 3, 2},答案为1,因为{3, 2}是无序的;对于数组{3, 2, 1},答案为3,因为{3, 2},{3, 1},{2, 1}都是无序的。
显然,这个问题可以通过O(n^2)的暴力解法或枚举所有可能的对并消除那些无效对来解决。
我的问题是,是否有更好的解决方案,因为它看起来像是一个动态规划问题。提供代码片段会很有帮助。
使用平衡二叉搜索树可以在 O(n log n)
时间内解决此问题。以下是该算法的伪代码:
tree = an empty balanced binary search tree
answer = 0
for each element in the array:
answer += number of the elements in the tree greater then this element
add this element to the tree
O(n log n)
的吗?我不太擅长复杂度分析,但从我的理解来看,一个单独的 for-loop
意味着 O(n)
。 - Alexandru SeverinO(log n)
。对于计算大于给定元素的数量,同样适用。因此,总时间复杂度为O(n * log n)
(即每次迭代需要O(log n)
的时间)。 - kraskevichdef merge_sort(l):
if len(l) <= 1:
return (0, l)
else:
mid = len(l) / 2
count_left, ll = merge_sort(l[0:mid])
count_right, lr = merge_sort(l[mid:])
count_merge, merged = merge(ll, lr)
total = count_left + count_right + count_merge
return total, merged
def merge(left, right):
li, ri = 0, 0
merged = []
count = 0
while li < len(left) and ri < len(right):
if left[li] < right[ri]:
merged.append(left[li])
li += 1
else:
count += 1
merged.append(right[ri])
ri += 1
if li < len(left):
merged.extend(left[li:])
elif ri < len(right):
merged.extend(right[ri:])
return count, merged
if __name__ == '__main__':
# example
l = [6, 1 , 2, 3, 4, 5]
print 'inverse pair count is %s'%merge_sort(l)[0]
这是我做练习试卷时遇到的问题,我认为嵌套的for循环可以很好地解决它。
public static void main(String args[])
{
int IA[] = {6,2,9,5,8,7};
int cntr = 0;
for(int i = 0; i <= IA.length-1;i++)
{
for(int j = i; j <= IA.length-1; j++)
{
if(IA[i]>IA[j])
{
System.out.print("("+IA[i]+","+ IA[j]+")"+";");
cntr++;
}
}
}
System.out.println(cntr);
}
merge(a, b):
i = 0
j = 0
c = new int[a.length+b.length]
inversions = 0
for(k = 0 ; k < Math.min(a.length, b.length); k++)
if(a[i] > b[j]):
inversions++
c[k] = b[j]
j++
else:
c[k] = a[i]
i++
//dump the rest of the longer array in c
return inversions
合并操作的时间复杂度为O(n)。整个归并排序的时间复杂度为O(n log n)。
c
变量? - Soravuxc
和 inversions
吗?否则,split 函数(调用 merge
)不会收敛,对吧? - Soravux