//视频教程:牛逼炸了:https://www.bilibili.com/video/BV1H5411c7oC?p=1&share_medium=android&share_plat=android&share_session_id=0b0a6ad0-f190-472d-88cd-679f55caa3c5&share_source=WEIXIN&share_tag=s_i×tamp=1651576411&unique_k=6u6VRqM
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
double findMedianSortedArras(vector<int> vec1, vector<int> vec2)
{
//寻找比较短的数组用于寻找切分点,用长的去寻找,即以长的为切分依据的时候,短的很有可能越界,
//得到vec1.size() <= vec2.size()
int lenVec1 = vec1.size();
int lenVec2 = vec2.size();
if (lenVec1 > lenVec2)
{
//方法一:得到vec1.size() <= vec2.size()
//vector<int> temp = vec1;
//vec1 = vec2;
//vec2 = temp;
//方法二:得到vec1.size() <= vec2.size()
return findMedianSortedArras(vec2, vec1);
}
//初始化切割线的区间
int cutMin = 0;
int cutMax = lenVec1;
//二分法在iMin与iMax的范围内寻找切割线cut1的位置
while (cutMin <= cutMax)
{
//取cut1为区间中间值
int cut1 = cutMin + (cutMax - cutMin) / 2;
int cut2 = (lenVec1 + lenVec2 + 1) / 2 - cut1;//通过cut1的位置确定cut2的位置,通过实际画图归纳可以得到这个结论
//交叉比较,注意交叉的前提是不能越界, 判断cut1的位置取得是偏大了还是偏小了
if (cut2 != 0 && cut1 != lenVec1 && vec2[cut2 - 1] > vec1[cut1])
{
cutMin = cut1 + 1;
}
else if (cut1 != 0 && cut2 != lenVec2 && vec1[cut1 - 1] > vec2[cut2])
{
cutMax = cut1 - 1;
}
else
{
int maxLeft = -1;
//cut1和cut2已经在了正确的位置上
if (cut1 == 0)
{
maxLeft = vec2[cut2 - 1];
}
else if(cut2 == 0)
{
maxLeft = vec1[cut1 - 1];
}
else
{
maxLeft = max(vec1[cut1 - 1], vec2[cut2 - 1]);
}
if ((lenVec1 + lenVec1) % 2 == 1) return maxLeft;
int minRight = -1;
if (cut1 == lenVec1)
{
minRight = vec2[cut2];
}
else if (cut2 == lenVec2)
{
minRight = vec1[cut1];
}
else
{
minRight = min(vec1[cut1], vec2[cut2]);
}
return (maxLeft + minRight) / 2.0;
}
}
}
int main()
{
vector<int> vec1 = { 3, 4, 5, 6 };
vector<int> vec2 = { 1, 2 };
double result = findMedianSortedArras(vec1, vec2);
cout << result << endl;
}