【LeetCode】【分治法】493. 翻转对 思路解析和代码

493. 翻转对

题目链接

个人思路

思路

与逆序对的分之思想类似,都是使用归并排序
一开始的思路是完全照搬逆序对的思路,在比较两个元素大小时判断是否存在二倍的关系。
不能按照逆序对求解的原因:
两元素比较大小的过程中,i,j指针不断后移,会出现还没有找到合适的i时,j已经后移并跳过了满足条件的j。正是由于指针后移会影响到指针的求解,因此要把问题求解过程在比较大小之前完成

个人思路代码

错误代码

void merge(vector<int>& nums, int L1, int R1, int L2, int R2){
     
    int i = L1, j = L2;
    int temp[maxn], index = 0;
    while(i <= R1 && j <= R2){
     
        if(nums[i] <= nums[j]){
     
            temp[index++] = nums[i++];
        }
        else{
     
        //!!!!!!!!!!
            if(nums[i] > 2 * nums[j]){
     //判断重要翻转对
                printf("%d %d\n", i, j);
                printf("%d %d\n", nums[i], nums[j]);
                ans += R1 - i + 1;
            }
         //!!!!!!!
            temp[index++] = nums[j++];
        }
    }
    while(i <= R1){
     
        temp[index++] = nums[i++];
    }
    while(j <= R2){
     
        temp[index++] = nums[j++];
    }
    for(int i = 0; i < index; ++i){
     
        nums[L1 + i] = temp[i];
    }
}

正确代码(归并排序)

class Solution {
     
public:
    int maxn = 50005;
    int ans = 0;
    void merge(vector<int>& nums, int L1, int R1, int L2, int R2){
     
        int i = L1, j = L2;

        while(i <= R1 && j <= R2)
        {
     
            if((long)nums[i] > 2*long(nums[j]))
            {
     
                ans += R1 - i + 1;
                j++;
            }
            else
                i++;
        }//先处理问题
    
        i = L1, j = L2;//重新初始化i,j
        int temp[maxn], index = 0;
        while(i <= R1 && j <= R2){
     
            if(nums[i] <= nums[j]){
     
                temp[index++] = nums[i++];
            }
            else{
     
                temp[index++] = nums[j++];
            }
        }
        while(i <= R1){
     
            temp[index++] = nums[i++];
        }
        while(j <= R2){
     
            temp[index++] = nums[j++];
        }
        for(int i = 0; i < index; ++i){
     
            nums[L1 + i] = temp[i];
        }
    }
    void mergeSort(vector<int>& nums, int left, int right){
     
        if(left < right){
     
            int mid = (left + right) / 2;
            mergeSort(nums, left, mid);
            mergeSort(nums, mid + 1, right);
            merge(nums, left, mid, mid + 1, right);
        }
    }
    int reversePairs(vector<int>& nums) {
     
        int n = nums.size() - 1;
        mergeSort(nums, 0, n);
        return ans;
    }
};

你可能感兴趣的:(LeetCode,算法,leetcode,数据结构,分治算法)