zoukankan      html  css  js  c++  java
  • 剑指Offer 55. 数组中的逆序对

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

    示例 1:

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

    思路:运用归并排序的特点,merge的过程中如果后面区间的数字比前面区间的数字要小的话,则可以利用下标关系一次计算出当前区间中的所有逆序对,从而优化时间复杂度,缺点就是归并排序会用到一个辅助数组,所以会增加空间复杂度,也算是一种用时间换取空间的思想。因为计算逆序对直接相减就可以算出来了,所以整体的时间复杂度仍然是排序过程的时间复杂度O(nlogn),空间复杂度为O(n)

    代码:

    class Solution {
    public:
        int count = 0;
        vector<int> dummy;
        void merge(vector<int>& nums, int s1, int e1, int s2, int e2) {
            int index = s1;
            int pos1 = s1;
            int pos2 = s2;
            while (pos1 <= e1 && pos2 <= e2) {
                if (nums[pos1] <= nums[pos2]) {
                    dummy[index++] = nums[pos1++];
                } else {
                    dummy[index++] = nums[pos2++];
                    count += e1 - pos1 + 1;
                }
            }
            while (pos1 <= e1) {
                dummy[index++] = nums[pos1++];
            }
            while (pos2 <= e2) {
                dummy[index++] = nums[pos2++];
            }
            for (int i = s1; i <= e2; ++i) {
                nums[i] = dummy[i];
            }
        }
    
        void func(vector<int>& nums, int s, int e) {
            if (s >= e) return;
            int mid = (s + e) / 2;
            func(nums, s, mid);
            func(nums, mid+1, e);
            merge(nums, s, mid, mid+1, e);
        }
    
        int reversePairs(vector<int>& nums) {
            int len = nums.size();
            dummy.resize(len);
            func(nums, 0, len - 1);
            return count;
        }
    };
    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    javascript如何判断一个对象是不是数组
    Socket 通讯
    XML 文件解析
    iOS 钥匙串 指纹识别 get和Post请求的区别
    MOS X 下Apache服务器配置,及日志读取
    iOS中图片动画的三种模式及基本的代码实现
    UI中 frame 与 transform的用法与总结
    Xcode 缓存 帮助文档 隐藏文件夹显示方法
    NSDate用法整理总结
    iOS沙盒机制的基本操作总结
  • 原文地址:https://www.cnblogs.com/h-hkai/p/14726006.html
Copyright © 2011-2022 走看看