HackerRank:Merge Sort: Counting
题目
In an array, , the elements at indices and (where ) form an inversion if . In other words, inverted elements and are considered to be "out of order". To correct an inversion, we can swap adjacent elements.
For example, consider the dataset . It has two inversions: and . To sort the array, we must perform the following two swaps to correct the inversions:
Given datasets, print the number of inversions that must be swapped to sort each dataset on a new line.
Function Description
Complete the function countInversions in the editor below. It must return an integer representing the number of inversions required to sort the array.
countInversions has the following parameter(s):
arr: an array of integers to sort .
Input Format
The first line contains an integer, , the number of datasets.
Each of the next pairs of lines is as follows:
The first line contains an integer, , the number of elements in .
The second line contains space-separated integers, .
Constraints
Output Format
For each of the datasets, return the number of inversions that must be swapped to sort the dataset.
Sample Input
2
5
1 1 1 2 2
5
2 1 3 1 2
Sample Output
0
4
Explanation
We sort the following datasets:
is already sorted, so there are no inversions for us to correct. Thus, we print on a new line.
We performed a total of swaps to correct inversions.
题目解析
核心就是Merge排序,注意在新建数组的时候直接赋值,append等会导致超时。就是用递归 每次都拿两个排序好的数组 merge排序
ANSWER
#!/bin/python3
import math
import os
import random
import re
import sys
# Complete the countInversions function below.
def merge(arr, left_half, right_half):
i, j, k = 0, 0, 0
inversions = 0
left_len, right_len = len(left_half), len(right_half)
while i < left_len and j < right_len:
if left_half[i] <= right_half[j]:
arr[k] = left_half[i]
i += 1
else:
arr[k] = right_half[j]
j += 1
inversions += left_len - i
k += 1
while i < left_len:
arr[k] = left_half[i]
i, k = i+1, k+1
while j < right_len:
arr[k] = right_half[j]
j, k = j+1, k+1
return inversions
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr)//2
left_half, right_half = arr[:mid], arr[mid:]
inversions = merge_sort(left_half) + merge_sort(right_half) + merge(arr, left_half, right_half)
return inversions
return 0
def countInversions(arr):
return merge_sort(arr)
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
t = int(input())
for t_itr in range(t):
n = int(input())
arr = list(map(int, input().rstrip().split()))
result = countInversions(arr)
fptr.write(str(result) + '\n')
fptr.close()