您的位置:首页 > 编程语言 > C语言/C++

(C++)剑指offer-6:旋转数组的最小数字

2018-02-12 13:42 323 查看

剑指offer-6:旋转数组的最小数字

目录

剑指offer-6旋转数组的最小数字

目录
1题目描述

2问题分析

3答案

4完整代码

1题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。



2问题分析

二分查找

首先能想到的就是顺序遍历,数组中最小的元素即为整个旋转数组的最小元素,但算法时间复杂度为O(n);

由旋转数组的特性,因为经排序好的数组旋转得到的,所以由其特性可以知道,除了不旋转的情况(即原数组),旋转数组可以划分为两个排序的子数组,前面的子数组元素均大于后面的子数组元素,存在分界线,所以可以想到的就是利用二分查找法,实现时间复杂度为O(logn);

注意考虑以下几种情况的处理:

1)数组元素为空的情况,(判断,直接返回0);

2)数组元素只有一个的情况,(判断,直接返回该元素);

3)数组旋转0个元素,也就是没有旋转的情况,(最后返回mid对应的值,所以初始时令mid=low,遇到该情况while条件不成立,依然返回mid对应的值);

4)如,排序数组为{0,1,1,1,1},旋转数组为{1,0,1,1,1}或者{1,1,1,0,1},当为这两种情况时,mid=low=high,无法确定最小的元素在左还是在右,所以这个时候就需要采用顺序查找的方式。

3答案

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size() == 0) return 0;
if(rotateArray.size() == 1) return rotateArray[0];

int low = 0;
int high = rotateArray.size()-1;
int mid = low;
while(rotateArray[low] >= rotateArray[high]){
// 结束条件
if(high - low == 1){
mid = high;
break;
}

mid = (low + high)/2;

//顺序查找
if(rotateArray[low] == rotateArray[high] && rotateArray[low] == rotateArray[mid])
return minInOrder(rotateArray, low, high);

if(rotateArray[mid] >= rotateArray[low])
low = mid;
else if(rotateArray[mid] <= rotateArray[high])
high = mid;
}

return rotateArray[mid];
}

int minInOrder(vector<int>& numbers, int low, int high){
int result = numbers[low];
for(int i = low+1; i<=high; ++i){
if(result > numbers[i])
result = numbers[i];
}

return result;
}
};


4完整代码

#include <iostream>
#include <vector>
using namespace std;

class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size() == 0) return 0; if(rotateArray.size() == 1) return rotateArray[0]; int low = 0; int high = rotateArray.size()-1; int mid = low; while(rotateArray[low] >= rotateArray[high]){ // 结束条件 if(high - low == 1){ mid = high; break; } mid = (low + high)/2; //顺序查找 if(rotateArray[low] == rotateArray[high] && rotateArray[low] == rotateArray[mid]) return minInOrder(rotateArray, low, high); if(rotateArray[mid] >= rotateArray[low]) low = mid; else if(rotateArray[mid] <= rotateArray[high]) high = mid; } return rotateArray[mid]; } int minInOrder(vector<int>& numbers, int low, int high){ int result = numbers[low]; for(int i = low+1; i<=high; ++i){ if(result > numbers[i]) result = numbers[i]; } return result; } };

int main(){
Solution s;

vector<int> num = {0,1,2,3,4,5};
//vector<int> num = {4,5,6,7,1,2,3};
//vector<int> num = {2,2,2,2
4000
,1,2};

int result = s.minNumberInRotateArray(num);
cout<<result<<endl;
}


运行结果

0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: