2つの順序付けられた配列の中央値を組み合わせる
OJアドレス:
2つの順序付けられた配列の中央値をマージします
O(log(m + n))が必要なため、最初の応答に2ポイントを使用しますが、2ポイントをどのように使用しますか?
配列AとBは別々に順序付けられています。最初に配列Aで分割線iを見つけることができるので、配列AはA_leftとA_rightの2つの部分に分割されます。次に、中央値を見つける必要があるため、B配列を直接計算できます。分割線jはsize(Aleft)+ size(Bleft)= size(Aright)+ size(Bright)になりますが、max(aleft、bleft)<min(aright、bright)でなければならないため、まだ終わっていません。 、したがって、この時点でiの値(2点)を調整してから、iの値からjの値を直接計算し、条件が満たされるまでループする必要があります。配列のサイズをn、iを分割点、bを配列のサイズはm、jは分割点です。全体的な条件は次のとおりです。
n + mが偶数の場合はi + j = n + mij、n + mが奇数の場合はi + j = n + m + 1-ij-> j =(n + m + 1)/ 2-i m> = n。。。n> mの場合、jは0未満である可能性があるため
a [i-1] <b [j]およびa [i]> b [j-1]
1
2
i、j = 0およびi = nの場合、j = m境界条件には特別な処理が必要であり、比較的単純です。たとえば
、i = 0またはj = mの場合、a [i-1] <b [j]をチェックする必要はなく、a [i]> b [jをチェックするだけです。 -1]
i> 0、m> = n-> j =(n + m + 1)/ 2-i <(m + n + 1)/ 2 <=(2m + 1)/ 2m
i <n、m> = n-> j =(n + m + 1)/ 2-i> =(2n + 1)/ 2-i>(2n + 1)/ 2-n0
1
2
ループの処理が簡単である
。I> 0及び[I-1]> B [j]が1 - > iが大きすぎる
I <N及び[I] <B [J-2。 1]-> iが小さすぎ
ます3.それ以外の場合、iは正しい位置にあります
コードは次のように表示されます。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if(nums2.size()<nums1.size())
{
return findMedianSortedArrays(nums2,nums1);
}
int n=nums1.size(),m=nums2.size();
int left = 0,right = n;
double max_left=-1,min_right=-1;
while(true)
{
int i = (right+left)/2;
int j = (m+n+1)/2-i;
if(i<n && nums1[i] < nums2[j-1]) //i is small
{
left=i+1;
}
else if(i>0 && nums1[i-1] > nums2[j] )// i is big
{
right = i-1;
}
else
{
if(i==0)max_left=nums2[j-1];
else if(j==0)max_left=nums1[i-1];
else max_left=max(nums1[i-1],nums2[j-1]);
if((n+m)%2)return max_left;
if(i==n)min_right=nums2[j];
else if(j==m)min_right=nums1[i];
else min_right=min(nums1[i],nums2[j]);
return (min_right+max_left)/2;
}
}
return -1;
}
};