一、前言
LeetCode第4题「寻找两个有序数组中位数」是经典算法题,全网教程、题解清一色围绕两个任意长度(m≠n)数组实现通用分割二分,依赖正负无穷哨兵值、大量边界if判断。
但在数据库归并Join、磁盘外排序、多传感器时序统计等真实工程场景中,业务常主动把有序数据集切分为长度完全相等的两段,通用二分在等长场景存在代码冗余、分支过多、极值溢出隐患。本文针对两数组等长L、1≤k≤L的限定场景,自研一套无哨兵、无边界特判的迭代二分算法,从不变量层面对比传统通用解法优劣。
#include
#include
using namespace std;
template
//约束:v1、v2长度均为L,1 ≤ k ≤ L
T find_kth(const vector& v1, const vector& v2, int L, int k)
{
int f1 = 0, e1 = k - 1;
int f2 = 0, e2 = k - 1;
int len = k;
while (len > 1)
{
int p1 = (f1 + e1) / 2;
int p2 = (f2 + e2) / 2;
if (v1[p1] > v2[p2])
{
e1 = p1;
f2 = len % 2 ? p2 : p2 + 1;
}
else if (v1[p1] < v2[p2])
{
f1 = len % 2 ? p1 : p1 + 1;
e2 = p2;
}
else return v1[p1];
len = e1 - f1 + 1;
}
return min(v1[f1], v2[f2]);
}
落地应用场景
1. 数据库Merge-Join:分库分表后两张分片数据等长有序,归并关联时频繁求分位数/中位数,替换通用二分降低内核计算开销; 2. 外排序多路归并:磁盘拆分后的有序块人工切分为等长数据,两两归并筛选第k元素; 3. 物联网时序数据:多传感器同频率采样,数据点数一致,批量统计分位数; 4. 算法竞赛:题目给定等长有序数组场景,卡常数时优于通用写法。