題目鏈接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。
示例:
輸入: [7,5,6,4]
輸出: 5
先說自己想法:暴力法先來一遍,嗯…超時了!!! 不知所措的我打開了題解,前面又是一片光明!!!
題解也有很多方法,這裏就主要用歸併排序,剛好也複習一下歸併排序。
這裏推薦去看官方講解視頻,不愧是官方出品:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/solution/shu-zu-zhong-de-ni-xu-dui-by-leetcode-solution/
代碼就是在歸併排序的基礎上添加了一個計數變量,當合並兩個子數組時,如果左邊的子數組中值大於右邊子數組的值,那麼左邊子數組中的元素個數就是逆序對的個數。所以,就很容易想到把這點代碼加到哪裏了。
class Solution {
public int reversePairs(int[] nums) {
if (nums.length == 0)
return 0;
return merge(nums, 0, nums.length - 1);
}
private int merge(int[] nums, int start, int end){
if (start == end){
return 0;
}
int mid = start + (end - start) / 2;
int count = merge(nums, start, mid) + merge(nums, mid + 1, end);
int i = start, j = mid + 1, k = 0;
int[] temp = new int[end - start + 1];
while (i <= mid && j <= end){
count += (nums[i] <= nums[j]) ? 0 : (mid - i + 1); // 在這裏加了統計變量,其他部分和歸併排序沒什麼變化
temp[k++] = (nums[i] <= nums[j]) ? nums[i++] : nums[j++];
}
while(i <= mid){
temp[k++] = nums[i++];
}
while(j <= end){
temp[k++] = nums[j++];
}
// 這一步是把排序好的部分填到原來數組中
for (int c = 0; c < k; c++){
nums[start + c] = temp[c];
}
return count;
}
}