【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;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值