LeetCode-4. 尋找兩個有序數組的中位數

地址:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

思路:一:利用兩指針遍歷直接找出第k小值即可

二:博客:https://blog.csdn.net/yutianzuijin/article/details/11499917
將a數組切前sa片,b數組切前k-sa片,通過對a[sa-1]和b[k-sa-1]大小比較,可捨棄掉其中一部分,從而實現二分查找出第K小值 

三:博客: https://blog.csdn.net/chen_xinjia/article/details/69258706
利用對a數組切前L1片,在通過對b數組切前L2=k-L1片,通過分析比較,可實現二分查找到第K小值 

Code:

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<map>
#include<unordered_map>
using namespace std;
typedef long long LL;

/*
class Solution {	//利用指針遍歷找第K小值  O(n+m)
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        double res=0;
        int l1=nums1.size()-1,l2=nums2.size()-1,h=(l1+l2+3)/2,p;
        while(h){
        	if(l1<0){
        		p=nums2[l2--];
			}else	if(l2<0){
				p=nums1[l1--];
			}else{
				if(nums1[l1]>nums2[l2]){
					p=nums1[l1--];
				}else{
					p=nums2[l2--];
				}
			}
			--h;
		}
		res=p;
		if((nums1.size()+nums2.size())%2==0){
			if(l1<0){
				res=(res+nums2[l2])/2;
			}else	if(l2<0){
				res=(res+nums1[l1])/2;
			}else{
				if(nums1[l1]>nums2[l2]){
					res=(res+nums1[l1])/2;
				}else{
					res=(res+nums2[l2])/2;
				}
			}
		}
        return res;
    }
};
*/


/*
https://blog.csdn.net/yutianzuijin/article/details/11499917
將a數組切前sa片,b數組切前k-sa片,通過對a[sa-1]和b[k-sa-1]大小比較,可捨棄掉其中一部分,從而實現二分查找出第K小值 
*/
/* 
class Solution {	//O(log(n+m))
public:
	int len1,len2;
	int Find_K_Min(vector<int>& nums1, vector<int>& nums2, int l1, int l2, int k){
		if(l1==len1)	return nums2[k-1];
		if(l2==len2)	return nums1[k-1];
		if(k==1)	return min(nums1[l1],nums2[l2]);
		int p1=min(k/2,len1-l1),p2=k-p1;
		if(p2>len2-l2){
			p2=len2-l2;	p1=k-p2;
		}
		if(nums1[l1+p1-1]<=nums2[l2+p2-1])	return Find_K_Min(nums1,nums2,l1+p1,l2,k-p1);
		else	return Find_K_Min(nums1,nums2,l1,l2+p2,k-p2);
	}
	
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        len1=nums1.size(),len2=nums2.size();
        double res=Find_K_Min(nums1,nums2,0,0,(len1+len2+1)/2);
        if((len1+len2)%2==0)	res=(res+Find_K_Min(nums1,nums2,0,0,(len1+len2)/2+1))/2;
        return res;
    }
};
*/ 

/*
https://blog.csdn.net/chen_xinjia/article/details/69258706
利用對a數組切前l1片,在通過對b數組切前l2=k-l1片,通過分析比較,可實現二分查找到第K小值 
*/
class Solution {	//O(log(min(n,m)))
public:
	int Find_K_Min(vector<int>& nums1, vector<int>& nums2,int k){	//找第k小值 
		int len1=nums1.size(),len2=nums2.size();
		if(len1+len2<k)	return -1;
		if(!len1)	return nums2[k-1];
		if(k==1)	return min(nums1[0],nums2[0]);
		if(k==len1+len2)	return max(nums1[len1-1],nums2[len2-1]);
		if(len1>=k&&nums1[k-1]<=nums2[0])	return nums1[k-1];
		if(len2>=k&&nums2[k-1]<=nums1[0])	return nums2[k-1];
		if(len1<k&&nums1[len1-1]<=nums2[k-len1])	return max(nums1[len1-1],nums2[k-len1-1]);
		if(len2<k&&nums2[len2-1]<=nums1[k-len2])	return max(nums2[len2-1],nums1[k-len2-1]);
		int l=max(0,k-len2),r=min(len1-2,k-2),h,l1,l2,res;
		bool boo;
		while(l<=r){
			l1=h=(l+r)/2;	l2=k-l1-2;
			boo=false;
			if(nums2[l2]>nums1[l1+1]){
				boo=true;
			}else	if(nums1[l1]<=nums2[l2+1]){
				r=h;	break;
			}
			if(boo)	l=h+1;
			else	r=h-1;
		}
		return max(nums1[r],nums2[k-r-2]);
	}
	
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    	int len1=nums1.size(),len2=nums2.size();
    	if(len1>len2){
    		swap(nums1,nums2);
    		swap(len1,len2);
		}
    	double res=Find_K_Min(nums1,nums2,(len1+len2+1)/2);
    	if((len1+len2)%2==0)	res=(res+Find_K_Min(nums1,nums2,(len1+len2)/2+1))/2;
    	return res;
    }
};


int main()
{
	int n,m,x;
	vector<int> v1,v2;
	Solution So;
	cin>>n>>m;
	for(int i=0;i<n;++i)
	{
		cin>>x;
		v1.push_back(x);
	}
	for(int i=0;i<m;++i)
	{
		cin>>x;
		v2.push_back(x);
	}
	cout<<So.findMedianSortedArrays(v1,v2)<<endl;
	
	return 0;
}

 

發佈了325 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章