算法:C++实现二分查找
2017-08-20 09:25
501 查看
事出有因,昨晚内推笔试题,采用遍历的方式提示耗时,由于系统原因(忍不住再次吐槽一下考试系统,估计是单线程队列模式),本地测试通过但是系统提交不上去,好不容易提交上去发现没通过全部的测试用例,当考虑用二分查找方式实现时时间已耗完。
题目:新兵入队,编号从1开始依次递增(10个人的话编号是1-10),共分成N个队伍,指定每个队伍中的人数并分配新兵(按照编号顺序),然后随机选取Q个测试qi(i=1-Q),指出编号为qi的新兵在哪一组。举例:新兵分为五组N=5,从第一组到第五组的人数分别为2,7,3,4,9。测试三个数据Q=3,编号为1的在第一组,编号为25的新兵在第五组,编号为11的新兵在第3组。
测试用例:
输入
输出:
思路:开始最先想到的是先记录每个组的编号的大小区间(例如测试用的第二组区间为3-9),然后根据每个编号,遍历每个组数判断是否在该组的区间内,如果在就输出,不在继续往后找。这种暴力的方式在本地编译没有问题,但是考试系统就出现了问题。由于编号是有序的,且按照有序的方式进行分组,满足二分查找的前提,我们可以记录当前组的最大编号形成一个序列(上述五个组分别为2 9 12 16 25),然后查找大于测试qi的最小数所在的组就解决了问题。重点是本来想自己实现二分查找,发现STL中已经集成了相关类型的函数模板lower_bound(),先实现一下:
附上常见的二分查找(递归和非递归):
有关STL二分查找的算法,可以参见另一篇博客STL二分查找算法。
题目:新兵入队,编号从1开始依次递增(10个人的话编号是1-10),共分成N个队伍,指定每个队伍中的人数并分配新兵(按照编号顺序),然后随机选取Q个测试qi(i=1-Q),指出编号为qi的新兵在哪一组。举例:新兵分为五组N=5,从第一组到第五组的人数分别为2,7,3,4,9。测试三个数据Q=3,编号为1的在第一组,编号为25的新兵在第五组,编号为11的新兵在第3组。
测试用例:
输入
5 2 7 3 4 9 3 1 25 11
输出:
1 5 3
思路:开始最先想到的是先记录每个组的编号的大小区间(例如测试用的第二组区间为3-9),然后根据每个编号,遍历每个组数判断是否在该组的区间内,如果在就输出,不在继续往后找。这种暴力的方式在本地编译没有问题,但是考试系统就出现了问题。由于编号是有序的,且按照有序的方式进行分组,满足二分查找的前提,我们可以记录当前组的最大编号形成一个序列(上述五个组分别为2 9 12 16 25),然后查找大于测试qi的最小数所在的组就解决了问题。重点是本来想自己实现二分查找,发现STL中已经集成了相关类型的函数模板lower_bound(),先实现一下:
#include<iostream> #include<vector> #include<algorithm> int main(){ long long num; std::cin>>num; long long count=0; std::vector<int> groups(num); for(long long i=0;i<num;++i){ long long temp; std::cin>>temp; groups[i]=count+temp; count+=temp; } long long q; std::cin>>q; long long qi; for(long long i=0;i<q;++i){ std::cin>>qi; long long mid=std::lower_bound(groups.begin(),groups.end(),qi)-groups.begin(); std::cout<<mid+1<<std::endl; } return 0; }
附上常见的二分查找(递归和非递归):
递归: int find(vector<int>const &vec,int start,int end,int value){ if(start>end){ return -1; } int mid=(start+end)>>1; if(vec[mid]==value){ return mid; } if(vec[mid]<value){ return find(vec,mid+1,end,value); } if(vec[mid]>value){ return find(vec,start,mid-1,value); } } 非递归 int find(vector<int>const &vec,int start,int end,int value){ while(start<=end){ int mid=(start+end)>>1; if(vec[mid]==value){ break; } if(vec[mid]<value){ start=mid+1; } else{ end=mid-1; } } return -1; }
有关STL二分查找的算法,可以参见另一篇博客STL二分查找算法。
相关文章推荐
- 算法-对分查找(二分查找)C++实现
- c/c++算法之正确实现二分查找
- 算法-对分查找(二分查找)C++实现
- 二分查找算法的C/C++实现
- 二分查找算法的C/C++实现
- c++ 实现快速排序与二分查找 源代码
- 算法之二分查找(c++版实现+测试)
- 二分查找算法递归实现
- 算法四 二分查找 java,c,c++
- 算法(第4版) 学习笔记二——二分查找的普通实现与递归实现
- 二分查找算法的递归与非递归实现
- 二分查找算法-递归-非递归实现
- 算法学习---基本数据类型的数组二分查找实现
- 二分查找C++实现
- 二分查找算法在C/C++程序中的应用示例
- C语言实现折半查找(二分查找)的算法
- 二分查找算法之python实现
- C语言二分查找算法及实现代码
- 顺序表创建以及查找排序算法(含有顺序查找算法、带哨兵站顺序查找、折半查找算法、冒泡排序)的C++实现在vs2013环境下实现
- c++/java/python 实现二分查找