程序员面试金典: 9.11 排序与查找 11.3找出已排序数组经过旋转后某个元素
2017-01-11 22:08
423 查看
#include <iostream> #include <stdio.h> #include <vector> using namespace std; /* 问题:给定一个排序后的数组,包含n个整数,但这个数组已经被旋转过很多次,次数不详。 请编写代码找出数组中的某个元素。可以假定数组元素原先是按照从小到大的顺序排列的。 分析:首先这里的旋转代表什么意思?应该是从某处将数组截断,将数组后半部分放到前面去了。 比如:1 2 3 4 5,从3处旋转,得到3 4 5 1 2 我们知道二分搜索是logN,这里如果用二分搜索感觉会失效,因为不是真正的每次都抛弃一半, 3 4 5 0 1 2,加入寻找的是0,发现0<5,然后往左边找,左边发现找来找去没有,说明可能在右边,对右半边搜索 输入: 6(数组中元素个数) 0(寻找的值) 3 4 5 0 1 2 6 2 4 5 0 1 2 3 6 3 2 2 2 2 3 2 6 3 2 3 2 2 2 2 6 3 2 2 2 2 2 2 输出 3(输出元素在数组中的下标,如果找不到返回-1) 4 4 1 -1 关键: 1 书上解法: 需要用中间元素和两边元素比较,确定哪一边是升序,然后进行搜索。 例子: 3 4 5 0 1 2 1)如果中间元素A[m] > 最左边元素A[l],说明左半部分是升序,判断查找值x 1.1)若A[l] <= x <= A[m],直接在左半部分寻找 1.2)否则,在右半部分寻找 例子: 4 5 0 1 2 3 2)如果A[m] < A[l],右半部分是升序, 2.1)如果A[m] <= x <= A[h],在右半部分寻找 2.2) 否则在左半部分寻找 例子: 2 2 2 2 3 2 2 3 2 2 2 2 3) 如果A[m] = A[l] 3.1)如果x = A[m],直接返回 3.2) 否则,3.2.1)如果A[h] != A[m],在有半部分寻找 3.2.2)如果A[h] = A[m],可能在左边也可能在右边(错,不要用顺序搜索,先搜索左边,再搜右边,根据是否查找到继续搜索,牛逼) */ int binarySearchRotation(vector<int>& datas , int low , int high , int value) { if(datas.empty() || low < 0 || high < 0) { return -1; } int middle; while(low <= high) { middle = low + (high - low) / 2 ; //找到 if(datas.at(middle) == value) { return middle; } //左边有序 if( datas.at(low) < datas.at(middle) ) { //查找值在左半部分 if( datas.at(low) <= value && value <= datas.at(middle) ) { return binarySearchRotation(datas , low , middle - 1 , value); } else { return binarySearchRotation(datas , middle + 1, high , value); } } //右边有序 else if( datas.at(low) > datas.at(middle) ) { //查找值在右半部分 if( datas.at(middle) <= value && value <= datas.at(high) ) { return binarySearchRotation(datas , middle + 1 , high ,value); } else { return binarySearchRotation(datas , low , middle - 1 , value); } } //左边和中间值相同 else { //如果右边值不和中间值相同,搜索右半部分 if( datas.at(middle) != datas.at(high) ) { return binarySearchRotation(datas , middle + 1 , high , value); } //如果左边,中间,右边所有的值相同,那么先搜左边如果左边搜索不到,搜索右边 else { int result = binarySearchRotation(datas , low , middle - 1 , value); if( -1 == result) { result = binarySearchRotation(datas , middle + 1 , high , value); } return result; } } } //如果low > high,还没找到,说明不存在 return -1; } void process() { int n; vector<int> datas; int num; int value; while(cin >> n >> num) { datas.clear(); for(int i = 0 ; i < n ; i++) { cin >> value; datas.push_back( value ); } //下面就是寻找这个值 int result = binarySearchRotation(datas , 0 , datas.size() - 1 , num); cout << result << endl; } } int main(int argc , char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 9.11排序与查找(三)——给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,找出数组中的某个元素
- 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素
- 程序员面试金典: 9.11 排序与查找 11.6给定M*N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。
- 程序员面试金典: 9.11 排序与查找 11.5有个排序后的字符串数组,其中散布这一些空字符串,编写一个方法,找出给定字符串的位置
- 程序员面试金典: 9.11 排序与查找 11.1给定两个排序后的数组A和B,其中A的末端有足够的缓冲容纳B。编写一个方法,将B合入A并排序。
- 程序员面试金典: 9.11 排序与查找 11.1编写一个方法,对字符串数组进行排序,将所有变位词排在相邻的位置。
- 9.11排序与查找(五)——有个排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的位置
- 程序员面试金典: 9.11 排序与查找 11.8求某元素在二叉查找树中的排名
- 11.3---旋转有序数组之后查找元素(CC150)
- 给定一个经过一次旋转的有序数组,从中查找一个值,若存在返回它的索引,不存在返回-1,假定数组存在重复元素
- 面试题精选(75):经过旋转的有序数组中的元素查找(要求复杂度为O(lgn))
- 33. Search in Rotated Sorted Array 在旋转的排序数组中查找元素
- 给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,找出数组中的某个元素
- 9.11排序与查找(六)——给定M*N矩阵,每一行、每一列都按升序排列,找出某元素
- 程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】
- 给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次,编写代码找出数组中的某个元素
- 找出两个数组中相同的元素,不排序直接两次循环取出
- 微策略面试题:在旋转后的数组中查找元素(二分查找)
- 程序员面试题目总结--数组(二)【二分查找、找出给定数字出现次数、两个有序整型数组交集、找出数组中唯一的重复元素、判断数组中的数值是否连续相邻】
- leetcode题解:Search in Rotated Sorted Array(旋转排序数组查找)