0
点赞
收藏
分享

微信扫一扫

两个有序区间寻找中位数(遇到了问题)

想溜了的蜗牛 2022-05-03 阅读 49
c++算法
//视频教程:牛逼炸了: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&timestamp=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;
}
举报

相关推荐

0 条评论