高效算法设计(二分查找,范围统计)

二分查找

二分查找一般写成非递归形式,输入数组,使用sort函数将数组排序。
  • 如果由多个相同的数,返回第一个数(lowerBound)。
  • 如果不存在,返回下标i,使i和i以后的往右移动。
输入:
8
1 9 6 3 4 7 9 0
3
8
1 9 6 3 4 7 9 0
5
输出:
2
4
#include <stdio.h>
#include<algorithm>
#define MAXSIZE 1024
using namespace std;
/*
int binarySearch(int *A,int x,int y,int val){
    while(x<y){//不能取等于,会陷入死循环
        int m=x+(y-x)/2;
        if(A[m]<val){
            x=m+1;
        }
        else if(A[m]>val){
            y=m;
        }
        else {
            return m;
        }
    }
    return -1;//如果改成x,就是val所在的位置。
}
*/
int lowerBound(int *A,int x,int y,int val){//下界
    while(x<y){//这是一个迭代过程,只有当x>y时才退出。
        int m=x+(y-x)/2;
        if(A[m]<val){
            x=m+1;
        }
        else if(A[m]>val){
            y=m;
        }
        else {
            return m;
        }
    }
    return x;
}
int upperBound(int *A,int x,int y,int val){//下界
    while(x<y){//这是一个迭代过程,只有当x>y时才退出。
        int m=x+(y-x)/2;
        if(A[m]<val){
            x=m+1;
        }
        else if(A[m]>val){
            y=m;
        }
        else {
            return m;
        }
    }
    return x;
}

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int A[MAXSIZE];
        for(int i=0;i<n;i++){
            scanf("%d",&A[i]);
        }
        sort(A,A+n);
        int val;
        scanf("%d",&val);
        printf("%d\n",upperBound(A,0,n,val));
    }
    return 0;
}

范围统计(上面的拓展)

题目:给出n个整数xi和m个询问,对于每个询问(a,b),输出闭区间[a,b]内的整数xi的个数。
输入:
8 3
0 1 3 4 6 7 9 9
3 9
0 1
0 9
输出:
6
6
2
2
8
8
#include <cstdio>
//#include <stdio.h>
#include <algorithm>//STL算法的头文件,包含sort,lower_bound,upper_bound等
using namespace std;
int v[10000];
int lowerBound(int *A,int x,int y,int val){
    int m;
    while(x<y){
        m=x+(y-x)/2;
        if(A[m]>=val) y=m;
        else x=m+1;
    }
    return x;
}
int upperBound(int *A,int x,int y,int val){
    int m;
    while(x<y){
        m=x+(y-x)/2;
        if(A[m]<=val) x=m+1;
        else y=m;
    }
    return x;
}
int main() {
    int n,m,a,b;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%d",&v[i]);
    sort(v,v+n);
    for(int i=0;i<m;i++){
        scanf("%d%d",&a,&b);
        printf("%d\n",upper_bound(v,v+n,b)-lower_bound(v,v+n,a));
        printf("%d\n",upperBound(v,0,n,b)-lowerBound(v,0,n,a));
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值