写在前面

看完labuladong的归并排序的应用后,准备稍稍总结下;来到题解区,翻了下三叶姐的题解(恐怖如斯,惊掉下巴~~)

前缀和

题目要求的是求满足条件的区间和 $S[i,j]$ 的个数,其中区间和是闭区间。也就是说找到符合题意的 $i<j$,满足 $lower<=S[i,j]<=upper$。考虑使用前缀和来快速求解。

  • 前缀和的使用
    • 前缀和 $preSum$ 的数组长度是原始数组的长度加1,首位置位零;对于任意的 $preSum[j]-preSum[i]$ ($i<j$),能够包含所有的区间和情况
    • 题目只需要求解满足条件的个数,因此简单了很多,不必要纠结下标的具体位置。
    • 因此问题就转换为,对于数组 $preSum$,求解符合题意的 $i,j$ 即可。
      • $i<j$ 且 $preSum[j]-preSum[i]$ 在 $[lower,upper]$ 范围内。

归并排序

归并排序是对 $preSum$ 数组进行操作,对于每一次merge的操作,记录左侧($i$ 的位置)与右侧($j$ 的位置)符合条件的个数,要注意的是因为左右两侧都是排序好的部分,有时可以利用这个条件减少计算

  • 归并排序的使用

    • 分而治之的思想,类似于二叉树的后序遍历,分解成子问题
    • 排序左侧,排序右侧,合并(merge)

合并左右

左右两侧都是已经排好序的数组,为了更好的合并,在开始前先复制拷贝一份

  • 合并两个有序数组
    • 双指针的思想,画出简图,更加容易理解
    • 本题不需要记录下标的位置,因此合并或称较为简单,简单排序即可。
  • 求解题目答案
    • 这部分可以放在双指针合并的过程中,也可以放在前面,主要是看哪种方便高效且不易出错。
    • 注意不要重复计算,边界条件,区间开闭情况等。

其他

对于 493. 翻转对 - 力扣(LeetCode) 问题,也仅仅是计数问题,不涉及元素下标问题,因此在合并排序时比较简单。

  • 需要记录对应下标
  • 数对的创建及使用

    • temp.push_back(make_pair(nums[i],i))
    • temp[i].first;temp[i].second(元素值及其索引位置)
  • 注意数据范围

    • 不同题目的数据范围不一样,因此在创建新的数组保存变量时,注意数据类型的设置
    • 类型强制转换:(int) data,(long long) data

$\cdots$ end $\cdots$