题目 思路 备注
    合并两个有序数组 尾部遍历比较,将较大的放到最后空位上
    第一个错误的版本 简单的二分查找即可
    颜色分类 题意即是让自行实现包含0/1/2三个元素的数组排序:
    左右夹逼双指针:[i,…k,…j], 解法如备注所示
    if(nums[k]==0) swap(nums[i], nums[k]); i++; k++
    if(nums[k]==2) swap(nums[j], nums[k]); j—
    if(nums[k]==1) k++;
    前K个高频元素 大顶堆,建完堆再依次输出到长度为k的数组中即可
    数组中的第K个最大元素 大顶堆,建完堆再执行k次poll操作
    寻找峰值 即找下降点,否则返回尾元素(递归数组) if(nums[i]>nums[i+1]) return i; //遇到了下降点
    在排序数组中查找元素的第一个和最后一个位置 两次独立的二分查找leftIdx和rightIdx:
    在方法一中:二分法找target的第一个位置
    在方法二中:二分法找找target的最后一个位置
    备注:关于二分法向上取整还是向下取整问题: 可归结为以下结论,以避免死循环:
    若出现 left =mid式赋值,须将mid趋于右侧[即, 上取整: mid=(l+r+1)/2]
    若出现right=mid式赋值,须将mid趋于左侧[即, 下取整: mid=(l+r)/2 ]
    合并区间 按每个数组的起始下标排一下序,再进行循环合并
    搜索旋转排序数组 二分查找法,只不过二分后,需要找到哪边是有序的部分,进而判断下一轮要在哪个区间查找
    搜索二维矩阵 二分查找, 从矩阵右上角向左下角查找,向左变小&向下变大,天然二分。 二分的目标是让两个范围反向变化(列向左变小,行向下变大)
    image.png
    摆动排序II image.png
    解法一:先对原数组排序,然后复制到两个数组中去,一个放大数,一个放小数。 然后将原数据偶数位放小数,奇数位放大数即可。
    解法二:桶排序,要先找到最大值做为桶的最大下标
    1. 声明一个能包含到最大值的桶,数组元素即做为桶的下标
    1. 对以数组元素值为下标的桶进行元素个数计数
    1. 每次从下标较大的桶开始,找到一个有效桶的下标
    1. 把这个较大的有效下标依次赋值给1/3/5/7/9等奇数位
    1. 再把较小的下标桶填入偶数位即可
    桶排序的关键代码——
    image.png
    有序矩阵中第K小的元素 两次二分查找法, 需要给定一个mid值,来计算该mid值左右两边的数的个数。用二分法思想,将这个个数逼近K. 具体:
    1. 先取中值:排序与搜索 - 图4
    1. 二分计算矩阵中满足排序与搜索 - 图5的x的个数:c
    1. 二分判断:排序与搜索 - 图6
    1. while条件是left
    注意:此题的二分法的“左”和“右”看着很不直观,是逻辑上的两个区域,计算目标值相对中值是偏左还是偏右,需要用如下的方式从左下往右上(二分)来统计数量。
    image.pngimage.png
    数据流中的中位数 小顶堆(放较大的一半数) & 大顶堆(放较小的一半数)。
    - 每当要插入元素时,优先插入元素少的那个堆(元素相等则插小顶堆), 但注意可能要交换堆顶,以保证左堆顶<=右堆顶
    寻找两个正序数组的中位数 用二分法找分隔线:在两个有序数组(a,b)中寻找【联合分隔线: i和j】,则中位数即是分隔线附近的元素。 注意:0<=i<=m, 0<=j<=n; 分隔线两侧的元素数量分别为:i+j 和 m+n-(i+j)。 即:如果在第一个数组中能找到i的合适位置,则j自然就确定了。
    同时,划线后目标i和j满足的条件应当是——
    1. m+n是偶数时,有: 排序与搜索 - 图9
    1. m+n是奇数(让左边多一个元素): 排序与搜索 - 图10
    1. 排序与搜索 - 图11时: 排序与搜索 - 图12 (如果i或j越了下界,则值取最小值,越了上界取最大值即可)
    联合分隔线示意图如下:
    image.png image.pngimage.png
    关键代码如下:
    image.png