leetcode 493 翻转对(分治排序,回溯)

题目描述:
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。

你需要返回给定数组中的重要翻转对的数量。

思路:
分治排序+回溯
首先利用分治排序的方法,分成两段,然后前半段和后半段进行比较

代码如下:

class Solution {
public:
    vector<int>tmp;
    int reversePairs(vector<int>& nums) {
        int n=nums.size();
        tmp.resize(n);
        return merge_sort(nums,0,n-1);
    }
    int merge_sort(vector<int>&nums,int left,int right){
        if(left>=right){
            return 0;
        }
        else{
            int mid=(right+left)/2;
            int cnt=merge_sort(nums,left,mid)+merge_sort(nums,mid+1,right);
            int j=mid+1;
            for(int i=left;i<=mid;i++){
                while(j<=right&&nums[i]/2.0>(double)nums[j]){
                    j++;
                }
                cnt+=j-(mid+1);
            }
            int p1=left,p2=mid+1;
            int p=left;
            vector<int>sorted(right-left+1);
            while(p1<=mid&&p2<=right){
                if(nums[p1]<nums[p2]){
                    tmp[p]=nums[p1];
                    p++;
                    p1++;
                }
                else{
                    tmp[p]=nums[p2];
                    p++;
                    p2++;
                }
            }
            while(p1<=mid){
                tmp[p]=nums[p1];
                p++;
                p1++;
            }
            while(p2<=right){
                tmp[p]=nums[p2];
                p++;
                p2++;
            }
            for(int i=left;i<=right;i++){
                nums[i]=tmp[i];
            }
            return cnt;
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值