归并排序变形算法题目思考(likou 493翻转对 & 327 区间和的个数)

493 翻转对题解分析

image.png

相对位置无关性

解决这题首先要明白一个事实,就是i < j其实可以理解为j的相对位置在i之后,或者是说不一定需要严格的要求保持nums[i]和nums[j]的位置。
就好比要统计两个数组a和b中,满足b[j] > a[i] 的总对数(a = [1,2,3], b=[1,7] 总对数是<1,7><2,7><3,7>这三对),b中元素的位置可以任意改变, 这并不会影响最终的统计结果。理解这一点后就很好理解归并排序中将两组合并前的排序过程,排序会改变元素的位置,但是前后两组的元素相对顺序是不变的,前一组元素一定在先(说的不清楚可以结合程序看)。

考虑统计a[i] > 2*b[j]

第二,考虑这样一个问题,给定升序数组 a=[1,4,5] 和 b=[2,3,5,6],统计出满足 a[i] > 2 * b[j] 的总个数。
可以这样考虑,初始设定让 left 指向a数组头部, right 指向b数组头部,判断 a[left] 和 2*b[right] 的大小,假如 a[left] 比较小,那说明对于b中任意元素,都不会有符合条件的情况出现,因为此时right指向b中最小元素,剩下的元素大于b[right],更不可能比a[left]小。left右移就。

while(left <= mid && nums[left] <= 2*(long)(nums[right])) left++;

直到这种情况不满足,此时满足题意的情况出现了,我们需要做的是统计满足情况的个数,并且继续增大right指针。 统计过程中,b[right]*2 < a[left], 那么数组a中右侧(更大的)元素一定都满足这一不等式,因此情况数应该加上从left到a数组结束的全部情形。

while(right<=high && nums[left] > 2*(long)(nums[right])){
    total+=(mid-left+1);
    right++;
}

类似的移动left和right,可得到本问题的解。

在此基础上,回到翻转对这一问题。是不是可以这样考虑。将整个数组通过归并的思路不断划分为小的片段。依次进行合并,合并的过程中我们保持了左右片段的顺序,但是无需考虑一个片段内部的元素顺序(因此可以在片段内进行排序,不会影响结果),两个片段之间的合并需要我们去统计这两个片段中 a[i] > 2 * b[j] 的个数,类似于上面的问题二。

while(left<=mid && right<=high){
        while(left <= mid &&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值