• 【LeetCode-数组】数组中的逆序对


    题目描述

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

    输入: [7,5,6,4]
    输出: 5
    

    说明: 0 <= 数组长度 <= 50000
    题目链接: https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/

    思路1

    暴力法。使用两层循环来做。代码如下:

    class Solution {
    public:
        int reversePairs(vector<int>& nums) {
            if(nums.empty()) return 0;
    
            int cnt = 0;
            for(int i=0; i<nums.size(); i++){
                for(int j=i+1; j<nums.size(); j++){
                    if(nums[i]>nums[j]) cnt++;
                }
            }
            return cnt;
        }
    };
    // 超时
    

    该方法超时。

    • 时间复杂度:O(n^2)
    • 空间复杂度:O(1)

    思路2

    使用归并排序来做。归并排序首先先将数组分为长度为 1 的子数组,然后两两进行合并。这题和归并排序的差别只有一行代码,我们在合并的时候,假设左边的数组为 [1, 3, 5],右边的数组为 [2, 4],现在左边数组的元素的下标 i 为 1,右边数组元素的下标 j 为 1,mid = 2,则我们可以找到 mid-i+1=2-1+1=2 个逆序对,分别是 (3, 2) 和 (5, 2)。所以我们在合并时,如果左边数组的元素大于右边数组的元素,我们就使用 mid-1+1 统计逆序对数,并加入到最终的答案当中。代码如下:

    class Solution {
    public:
        int reversePairs(vector<int>& nums) {
            if(nums.empty()) return 0;
    
            cnt = 0;
            mergeSort(nums, 0, nums.size()-1);
            return cnt;
        }
    
        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);
            }
        }
    
        void merge(vector<int>& nums, int left, int mid, int right){
            vector<int> temp(right-left+1, 0);
            int i = left;
            int j = mid+1;
            int k = 0;
    
            while(i<=mid && j<=right){
                if(nums[i]<=nums[j]) temp[k++] = nums[i++];
                else{
                    cnt += mid-i+1; // 比常规的归并排序只多这一行代码
                    temp[k++] = nums[j++];
                }
            }
            while(i<=mid) temp[k++] = nums[i++];
            while(j<=right) temp[k++] = nums[j++];
    
            for(int t=0; t<temp.size(); t++) nums[left+t] = temp[t];
        }
    
    private:
        int cnt;
    };
    
    • 时间复杂度:O(nlogn)
    • 空间复杂度:O(nlogn)

    参考

    https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/solution/jian-dan-yi-dong-gui-bing-pai-xu-python-by-azl3979/

  • 相关阅读:
    如何使用Junit
    CSS简单动画效果
    编程类软件下载地址
    常用的工具包-下载地址
    连接数据库常用工具类(二)------C3P0Utils工具类
    连接数据库时常用的工具类(一)-------C3P0XmlUtils
    浏览器输入服务器端口号来访问html网页
    使用C/S结构实现客户端上传本地文件到服务器
    冒泡排序
    一个注册界面
  • 原文地址:https://www.cnblogs.com/flix/p/13377998.html
Copyright © 2020-2023  润新知