493. Reverse Pairs

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]
Output: 2

Example2:

Input: [2,4,3,5,1]
Output: 3

Note:

  1. The length of the given array will not exceed 50,000.
  2. All the numbers in the input array are in the range of 32-bit integer.

Subscribe to see which companies asked this question.



给一个序列,要求求出其中“重要反转对”的个数。如果用暴力的方法对每个数nums[i]都找一遍符合nums[i] > 2*nums[j],要运算n*(n-1)/2次。参考discuss的答案。。用merge_sort的想法来实现。对当前的序列二分,对每个子序列,求出在每个子序列中“重要反转对”的个数(递归实现),然后对每个子序列用merge_sort排序。这样得到两个子序列各自的“重要反转对”的个数,还有排序后的子序列,然后两个子序列各自的“重要反转对”的个数的和,再加上第一个子序列中的数和第二个子序列中的数作比较符合要求的总数(因为已经排好序所以容易实现),就能得到当前序列的“重要反转对”的个数,最后将两个子序列merge_sort并返回当前结果。要注意的是比较nums[i] > 2*nums[j]时,会出现2*nums[j]溢出int的范围,所以要注意转换成long long。


代码:

class Solution
{
public:
	int reversePairs(vector<int>& nums) 
	{
		return merge_count(nums.begin(), nums.end());
	}
private:
	int merge_count(vector<int>::iterator begin, vector<int>::iterator end)
	{
		if(end - begin <= 1) return 0;
		auto mid = begin + (end - begin) / 2;
		int cnt = merge_count(begin, mid) + merge_count(mid, end);
		for(auto i = begin, j = mid; i != mid; ++i)
		{
			while(j != end && *i > 2L * *j)
			{
				++j;
			}
			cnt += (j - mid);
		}
		inplace_merge(begin, mid, end);
		return cnt;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值