Sword Finger Offer Interview Question 51: Reversed Pairs in an Array

When doing this question, the first thing that comes to my mind is to traverse one by one from the front to the back and find the reverse pair. The time complexity is n^2 and it will definitely not be passed.

Later, it was discovered that the reverse order relationship is related to the size of the number and can be carried out by sorting, but there is a problem with sorting, that is, after the number position is changed, the subsequent calculation of the number is almost impossible to achieve.

 

After reading the idea of ​​the answer, the idea of ​​solving this problem is to split the array into adjacent arrays of length one. For adjacent ones, determine the size, count the reverse order, and merge them. After merging, due to the two numbers The order of, will not affect the other statistical values ​​in the reverse order other than these two numbers, so the two numbers are sorted, and then the merged arrays are recursively merged and sorted in pairs.

 

The recursive call of the answer code, the copy array and the data array are recursive once and exchanged once, which is difficult to understand.

Because each layer operates on the data in the data and merges it into the copy. Therefore, alternate calls during recursion means that the data called by the current function is a sub-recursive copy, and the merged sub-recursive copy is obtained after the sub-recursive copy. The data is used as the parent's recursive data, and then the child's recursive data is used as a container to store the value of the parent's recursive copy array through calculation.

 

    public int reversePairs(int[] nums) {
        if(nums.length == 0){
            return 0;
        }  
        int[] copy = new int[nums.length];
        for(int count = 0;count<nums.length;count++){
            copy[count] = nums[count];
        }

        int res = reversePairsDivide(nums,copy,0,nums.length-1);
        return res;
    
    }
    public int reversePairsDivide(int[] data,int[] copy,int start,int end) {
        if(start == end){
            return 0;
        }
        int data_length = end - start;
        int mid = data_length/2;
        int left = reversePairsDivide(copy,data,start,start+mid);
        int right = reversePairsDivide(copy,data,start+mid+1,end);
        int i = start + mid;
        int j = end;
        int copyIndex = end;
        int res = 0;
        while(i>= start&& j>=start + mid + 1){
            if(data[i]>data[j]){
                res += (j - start - mid);
                copy[copyIndex--] = data[i--];
            }else{
                copy[copyIndex--] = data[j--];
                
            }
        }

        for(;i>=start;){
            copy[copyIndex--] = data[i--];
        }

        for(;j>=start + mid + 1;){
            copy[copyIndex--] = data[j--];
        }
        return res + left + right;
    }

 

Guess you like

Origin blog.csdn.net/qq_40473204/article/details/114636518