先看第一题,简单的二分查找,熟悉使用即可;
Position BinarySearch( List L, ElementType X ){
int left=1,right=L->Last,mid;
while(left<=right){
mid=(left+right)/2;
if(L->Data[mid]==X){
return mid;
}else if(L->Data[mid]>X){
right=mid-1;
}else{
left=mid+1;
}
}
return NotFound;
}
再看第二题,也是二分法的简单应用
bool Insert( List L, ElementType X ){
if(L->Last+1==MAXSIZE){
return false;
}
int right=L->Last,left=0,mid;
while(left<=right){
mid=(left+right)/2;
if(L->Data[mid]==X){
return false;
}else if(L->Data[mid]<X){//递减
right=mid-1;
}else{
left=mid+1;
}
}
for(int i=L->Last;i>=left;i--){
L->Data[i+1]=L->Data[i];
}
L->Data[left]=X;
++L->Last;
return true;
}
最后一题对我来说比较像奥数题,有一些数学规律,没有证明的话无法使用二分法解决;与此同时,使用时间复杂度更高的简单思路解决时平台的耗时居然更少,不清楚原因;
先是O(n)的思路,如下:
#include <stdio.h>
void input(int arr[],int n){
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
}
int main(){
int n;
scanf("%d",&n);
int a[n],b[n];
input(a,n);
input(b,n);
int r=0,s=0;
while(r+s<n-1){//当r+s==下标n-1时,为中位数;
if(a[r]<=b[s]){
r++;
}else{
s++;
}
}
int mid=a[r]<b[s]?a[r]:b[s];
printf("%d",mid);
return 0;
}
然后是logn的二分法思路,比较复杂;建议画图理解;
#include<iostream>
#include<vector>
using namespace std;
void cin_vector(vector<int>&v,int n) {
int m;
while (n--) {
cin >> m;
v.push_back(m);
}
}
int middle(vector<int>&v1, vector<int>&v2) {
int left1 = 0, right1 = v1.size() - 1, left2 = 0, right2 = v2.size() - 1;
int mid1, mid2;
while (left1 < right1 && left2 < right2) {
mid1 = (left1 + right1) / 2;
mid2 = (left2 + right2) / 2;
if (v1[mid1] == v2[mid2]) {
return v1[mid1];
}
else if (v1[mid1] > v2[mid2]) {
if ((left1 + right1) % 2 == 0) {
right1 = mid1;
left2 = mid2;
}
else {
right1 = mid1;
left2 = mid2 + 1;
}
}
else {
if ((left1 + right1) % 2 == 0) {
left1 = mid1;
right2 = mid2;
}
else {
left1 = mid1+1;
right2 = mid2;
}
}
}
return v1[left1] < v2[left2] ? v1[left1] : v2[left2];
}
int main() {
int n;
cin >> n;
vector<int>v1;
vector<int>v2;
cin_vector(v1,n);
cin_vector(v2,n);
cout<<middle(v1, v2);
return 0;
}