【LeetCode】面试题51. 数组中的逆序对

解题思路

分治法:
采用的就是归并函数中的分治思想,该题与分治排序的不同点在于,在治的过程中进行逆序对的统计,逆序对的个数为
cnt += center - i + 1;
这也是在归并排序上要加的代码

代码

/*
思路:分治
通过分的方式,获得每个子区间,在合并每个子区间时计算每个子区间内部的逆序对个数
*/
#include<iostream>
#include <vector>
using std::vector;
class Solution {
	int cnt = 0;
public:
	int reversePairs(vector<int>& nums) {
		if (nums.size() < 2) return 0;//特判,size为0,1不可能出现逆序对
		vector<int> temps(nums.size());
		mergeSort(nums, temps, 0, nums.size() - 1);
		return cnt;
	}
	//归并排序
	void mergeSort(vector<int>& nums, vector<int>& temps, int left, int right) {
		if (left < right) {
			int center = left + (right - left) / 2;
			mergeSort(nums, temps, left, center);//左分
			mergeSort(nums, temps, center + 1, right);//右分
			merge(nums, temps, left, center, right);//治
		}
	}
	//合并
	void merge(vector<int>& nums, vector<int>& temp, int left, int center, int right) {

		int i = left, j = center + 1;
		for (int k = left; k <= right; k++) {
			if (i > center) {//左边的已经比较完,将右边的全部放到temp中
				temp[k] = nums[j++];
			}
			else if (j > right) {//右边的已经比较完,将左边的全部放到temp中
				temp[k] = nums[i++];
			}
			else if (nums[i] > nums[j]) {//左边大于右边,出现逆序对,
				temp[k] = nums[j++];//取右边数组值
				cnt += center - i + 1;//此处+1是因为center是等于right的,这里也是比归并排序多的一行代码
			}
			else//左边小于等于右边
			{
				temp[k] = nums[i++];//取左边数组值
			}
		}
		//将temp中的元素复制到nums中
		for (int k = left; k <= right; k++) {
			nums[k] = temp[k];
		}
	}

};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章