class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n=nums1.size();
int m=nums2.size();
//保证数组1一定最短
if (n>m)
{
return findMedianSortedArrays(nums2,nums1);
}
//Ci 为第i个数组的割,比如C1为2时表示第1个数组只有2个元素。LMaxi为第i个数组割后的左元素。RMini为第i个数组割后的右元素。
int LMax1,LMax2,RMin1,RMin2,c1,c2,lo=0,hi=2*n; //我们目前是虚拟加了‘#’所以数组1是2*n长度。 //c1相当于割线
//lo为合并后最左边的数标,hi为最右边的数标,而lo不断增加,hi会减少,直到结束循环
while(lo <= hi)
{
//用c1标记合并后前一半元素个数
c1=(lo+hi)/2;
//用c2标记后一半元素个数
c2=n+m-c1;
//特殊情况,c1等于0或末尾值时相当于数组1左边为空,此时要保证左边小于右边,LMax1 = INT_MIN或RMin1= INT_MAX否则就正常情况处理,即割线的下标为奇数则c1-1/2的值刚好等于没有加‘#’的数组的值 ,,偶则c1/2-----前提条件每个数组都加了一倍元素的‘#’
LMax1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) / 2];
RMin1 = (c1 == 2 * n) ? INT_MAX : nums1[c1 / 2];
LMax2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) / 2];
RMin2 = (c2 == 2 * m) ? INT_MAX : nums2[c2 / 2];
//如果割线位置不符合规则->左边的小于右边的则割线调整位置
//h1和lo只是记录了合并数组有多长然后不断缩小范围,c1 和c2是割线
//if的条件只考虑对角的 不考虑同一个数组的,同一数组已经排好序了后边肯定小于前边,肯定得和规制
if (LMax1 > RMin2)
hi = c1 - 1;
else if (LMax2 > RMin1)
lo = c1 + 1;
else
break;
}
//计算左边最大的和右边最大的然后平均
return (max(LMax1, LMax2) + min(RMin1, RMin2)) / 2.0;
}
};