pat每日刷题计划--day70
作者:互联网
二分法
- binarySearch找的是出现在a数组中的,数值等于num的数的下标。(有多个的时候是随机的输出了一个)
- lowerbound找的是在a数组中出现的第一个,数值大于等于num的数的下标
- upperbound找的是a数组中出现的第一个,数值大于num的数的下标
找具体的某个数,是使用mid进行判断,而另外的两个是使用的left和right夹逼。
也正是因此,根据定义可以判断,在binarySearch中,不是对应返回值的a[mid]里面一定不包含正确答案,所以在转移的过程中不需要带上mid
在递增序列里面,binarySearch在a[mid]变迁:
- a[mid]==num ----> return mid
- a[mid]>num ----> right=mid-1
- a[mid]<num ---->left=mid+1
- 判定条件:left<=right,(只要mid,left,right都是合法的就有可能,因此需要带上等号)
而在lowerbound中,最终的一个位置是left==right,然后返回left的下标,在走完数组之前,并不知道当前的位置是真正的第一个。
- a[mid]>=num ----> 结果一定在[left,mid]中,right=mid
- a[mid]<num ---->可以确定mid处是不可能的,所以left=mid+1
- 循环条件:left<right 因为这样最后一次出来的是left=right
在upperbound中,最终也是left==right
- a[mid]>num ---->结果一定在[left,mid]中,right=mid
- a[mid]<=num ---->mid是不在范围内的,left=mid+1
- 循环判定:left<=right,最终以left=right退出循环
lowerbound和upperbound都可以被称为:寻找有序序列中第一个满足某条件元素的位置,只要设置好对应的边界判定就可以完成转换
binarySearch对应的判断问题是:判断一个有序序列中是否存在某个元素,如存在找出位置
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; int binarySearch(int a[],int left,int right,int num)//找出num在a数组的位置 { int mid=(left+right)/2; while(left<=right) { mid=(left+right)/2; if(a[mid]==num) return mid; if(a[mid]>num) right=mid-1; else left=mid+1; } return -1; } int lowerbound(int a[],int left,int right,int num)//找出大于等于num的第一个数在a数组的位置 { int mid=(left+right)/2; while(left<right) { mid=(left+right)/2; if(a[mid]>=num) { right=mid; } else left=mid+1; } return left; } int upperbound(int a[],int left,int right,int num)//找出第一个大于num的数在a数组中的位置 { int mid=(left+right)/2; while(left<right) { mid=(left+right)/2; if(a[mid]>num) right=mid; else left=mid+1; } return left; } int main() { int n=5; int a[15]={1,3,3,3,6}; /*for(int i=0;i<n;i++) scanf("%d",&a[i]);*/ printf("%d\n",binarySearch(a,0,n-1,3)); printf("%d\n",lowerbound(a,0,n-1,3)); printf("%d\n",upperbound(a,0,n-1,3)); return 0; }View Code
标签:right,pat,int,mid,binarySearch,day70,num,刷题,left 来源: https://www.cnblogs.com/tingxilin/p/12241755.html