pta二分法使用总结

先看第一题,简单的二分查找,熟悉使用即可;

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;
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值