zoukankan      html  css  js  c++  java
  • <leetcode c++>面试题51. 数组中的逆序对

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

    很容易想到从后往前折半插入排序时顺便记录比当前数小得数,但是这种方法在用例30的时候就超时了。。

    class Solution {
    public:
        int count(vector<int>& nums, int pivot, int st, int ed){
            int l=st,r=ed;
            if(nums[pivot]<=nums[st])return 0;
            if(nums[pivot]>nums[ed]){
                int tmp=nums[pivot];
                for(int i=st;i<=ed;i++){
                    nums[i-1]=nums[i];
                }
                nums[ed]=tmp;
                return ed-st+1;
            }
            while(l<r){
                int mid=l+(r-l)/2;
                if(nums[mid]>=nums[pivot])
                    r=mid;
                else
                    l=mid+1;
            }
            int tmp=nums[pivot];
            for(int i=st;i<l;i++){
                nums[i-1]=nums[i];
            }
            nums[l-1]=tmp;
            return l-st;
        }
        int reversePairs(vector<int>& nums) {
            //从后往前折半插入排序
            int n=nums.size();
            int res=0;
            for(int i=n-2;i>=0;i--){
                res+=count(nums,i,i+1,n-1);
            }
            return res;
        }
    };

    然后我就思考毕竟插入排序要移动数组元素,最后的总体时间复杂度是O(n^2),那么找到一个插入和比较都是logn复杂度的算法不就可以了吗,那不就是归并排序吗!

    当然,需要O(n)的额外空间,时间复杂度为O(logn)

    class Solution {
    public:
        int res=0;
    
        void merge(vector<int>& nums, int left, int mid, int right){
            vector<int> tmp(right-left+1,0);
            int l1=left,l2=mid+1,l3=0;
            while(l1<=mid&&l2<=right){
                if(nums[l1]<=nums[l2]){
                    tmp[l3++]=nums[l1++];
                    res+=(l2-mid-1);
                }
                else
                    tmp[l3++]=nums[l2++];
            }
            while(l1<=mid){
                tmp[l3++]=nums[l1++];
                res+=(l2-mid-1);
            }
            while(l2<=right)tmp[l3++]=nums[l2++];
            for(int i=left;i<=right;i++){
                nums[i]=tmp[i-left];
            }
        }
    
        void mergeSort(vector<int>& nums, int left, int right){
            if(left<right){
                int mid = left+(right-left)/2;
                mergeSort(nums,left,mid);
                mergeSort(nums,mid+1,right);
                merge(nums,left,mid,right);
            }
        }
            
        int reversePairs(vector<int>& nums) {
            //归并排序
            int n=nums.size();
            mergeSort(nums,0,n-1);
            return res;
        }
    };
  • 相关阅读:
    jdbc连接Sql server数据库,并查询数据
    HttpClient,post请求,发送json,并接收数据
    SQL SERVER存储过程一
    HttpClient,get请求,发送并接收数据
    工作中操作数据库实例
    存储过程的实例(公司)
    eclipse发布项目后,项目所在的位置
    SQLSERVER存储过程基本语法
    SAXReader解析
    导包
  • 原文地址:https://www.cnblogs.com/Dancing-Fairy/p/12770553.html
Copyright © 2011-2022 走看看