Counting Inversions in an Array
题目
Given an array of distinct integers, an inversion is a pair of indices with .
Count the inversions in time. Then explain what the inversion count measures statistically.
解析
先自己试一试,卡住了再打开提示。
查看解析
Approach — merge sort with a counter. During the merge of two sorted halves, when an element from the right half is emitted ahead of remaining elements in the left half, those elements each form an inversion with it. Accumulate as you merge.
def count_inversions(a):
def sort_count(xs):
if len(xs) <= 1:
return xs, 0
mid = len(xs) // 2
left, cl = sort_count(xs[:mid])
right, cr = sort_count(xs[mid:])
merged, cm = [], 0
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
merged.append(left[i]); i += 1
else:
merged.append(right[j]); j += 1
cm += len(left) - i # all remaining left elems invert
merged += left[i:] + right[j:]
return merged, cl + cr + cm
return sort_count(a)[1]Recurrence gives time and space.
Alternative. Compress values to ranks and sweep right-to-left with a Binary Indexed Tree, querying the count of already-seen smaller values. Same complexity, often preferred when the array is streaming.
The statistical connection — this is the real question. The inversion count is exactly the unnormalised version of Kendall's tau:
So an inversion counter is an rank-correlation estimator. That matters in practice because Kendall's tau is robust to outliers and monotone transformations in a way Pearson correlation is not — which is why it shows up when scoring a signal against forward returns on heavy-tailed data.
Edge cases to mention: ties (decide vs and stay consistent; ties need the tau-b correction), and overflow — can reach , so use 64-bit.