题解 | #数组中的逆序对#

数组中的逆序对

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

#include <vector>

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
	 * 这是二路归并排序的算法题,重点是需要一个辅助的数组,将原来的数据存放到辅助的数组
	 一旦存放到辅助数组上,再下一轮的合并中,原始数据的位置就会成为目的地址,或者将上一轮的两个有序
	 子序列的内容,先放到原始数组中,合并时再放到dst数组中,这样保存了dst的属性在整个算法的含义一致性,
	 但也由此消耗了一些性能;
     * 
     * @param nums int整型vector 
     * @return int整型
     */
    int InversePairs(vector<int>& nums) {
      if (nums.empty() || nums.size() == 1)
        return 0;

      std::vector<int> dst(nums.size(), -1);
      return InversePairs(nums, dst, 0, nums.size()-1);
    }

    int InversePairs(vector<int>& nums, vector<int>& dst, int left, int right) {
      if (left >= right) {
        dst[left] = nums[left];
        return 0;
      }
  
      auto mid = left + ((right - left) >> 1);
      auto ret = InversePairs(nums, dst, left, mid) + InversePairs(nums, dst, mid+1, right);
      ret %= mod_;
      // InversePairs返回的结果放在dst中,而nums中的数据已不需要了。
      // 这个时候,为了保证合并之后的正确的序列仍然放在dst中,可以将nums和dst子left和right之间的数据进行交换;
      for (int i = left; i <= right; ++i) {
        nums[i] = dst[i];  
      }

      auto i = mid, j = right;
      auto k = right;
      auto count = 0;
      while (i >= left && j >= mid+1) {
        if (nums[i] > nums[j]) {
          count += j - mid; // 累加逆序对个数
          dst[k--] = nums[i--]; // 排序,将当前最大放入到dst中
        } else {
          dst[k--] = nums[j--]; // 排序,将当前最大放入到dst中
        }
      }

      while (i >= left)  // 如果右边的数组已无数据,就需要将左边的数据放入dst数组中
        dst[k--] = nums[i--];
      
      while (j >= mid+1)// 如果左边的数组已无数据,就需要将右边的数据放入到dst数组中
        dst[k--] = nums[j--];
      
      return (ret + count) % mod_;
    }

  private:
   int mod_ {1000000007};
};

全部评论

相关推荐

05-12 17:28
已编辑
门头沟学院 硬件开发
ldf李鑫:不说公司名祝你以后天天遇到这样的公司
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务