面試題51——數組中的逆序對

題目鏈接: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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章