アルゴリズム20日
7日目
2 つの順序配列の中央値を求める
2 つの配列が与えられた場合、結合後の中央値を見つけます。必要な時間計算量は log(m+n) です。
/例 cin>>nums1=[1,3],nums2=[2]
cout<<2.00000
説明: 配列をマージして中央値を見つけます。 /
この質問は基礎の重要性を反映しています。バイナリ マージ ソートを作成するときに、マージの関数を作成しました。この質問を見たとき、私はすぐに次のように反応しました。
#include<bits/stdc++.h>
using namespace std;
vector<int> HeBing(vector<int> &a,vector<int> &b)
{
vector<int> temp;
int i=0,j=0;
while(i<a.size()&&j<b.size())
{
if(a[i]>=b[j])
{
temp.push_back(b[j]);
j++;
}
else
{
temp.push_back(a[i]);
i++;
}
}
while(i<a.size())
{
temp.push_back(a[i]);
i++;
}
while(j<b.size())
{
temp.push_back(b[j]);
j++;
}
return temp;
}
double Mid(vector<int> &temp)
{
if(1&temp.size())//判断奇数还是偶数个
return temp[temp.size()/2];
else
return (double)(temp[temp.size()/2]+temp[temp.size()/2-1])/2;
}
int main()
{
vector<int> a={
1,2};
vector<int> b={
3,4};
vector<int> temp=HeBing(a,b);
printf("%0.5f",Mid(temp));
}
時間計算量がタイトルの要件を満たしていないので明日書きます
ログを見て二分法を使おうと思ったのですが、どうすれば二分化できるのでしょうか?まず、中央値は中央の数値であるため、k 番目の数値を見つけて、二分法を使用して問題を 2 つに分割するだけで済みます。
つまり、次のすべての要素の中で 5 番目に小さい数値を見つけます。
配列 a と b の場合、 a [k/2-1]<b[k/2-1] の場合、 k 番目に小さい数値は a[k/2-1] 以前であるため、 a[k/2-1] を除外できます。 ] とその前の数値 At most k/2+k/2-1 (b[k/2-1] とその前の数値が a[k/2-1] 未満の場合)、この時点で 2 つの要素は除外したら今 残った要素のうち、kk/2番目に大きい数を求める必要があります
k==1までは最後まで終わらない 偶数の場合はk+1番目に大きい数を求めれば良い
#include<bits/stdc++.h>
using namespace std;
int f(vector<int> &nums1,vector<int> &nums2,int k)
{
int m=nums1.size();
int n =nums2.size();
int index1=0,index2=0;
while(true)
{
if(index1==m)
return nums2[index2+k-1];
if(index2==n)
return nums1[index1+k-1];
if(k==1)
return min(nums1[index1],nums2[index2]);
int i=min(index1+k/2-1,m-1);
int j=min(index2+k/2-1,n-1);
int pivot1=nums1[i];
int pivot2=nums2[j];
if(pivot1<=pivot2)
{
k-=i-index1+1;
index1=i+1;
}
if(pivot1>pivot2)
{
k-=j-index2+1;
index2=j+1;
}
}
}
double m(vector<int> &nums1,vector<int> &nums2)
{
int length=nums1.size()+nums2.size();
if(length%2==1)//判断奇偶
return f(nums1,nums2,(length+1)/2);
else
return (f(nums1,nums2,length/2)+f(nums1,nums2,length/2+1))/2.0;
}
int main()
{
vector<int> a={
1,2};
vector<int> b={
3,4};
double temp=m(a,b);
printf("%0.5f",temp);
}
時間計算量 O(log(m+n));