《剑指offer》—6、旋转数组的最小数字

 题目描述
6、把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

解题思路:
1、题目考察的是查找和排序,数组旋转后,我们可以看成变成了两个非递减有序排列的子数组,且前面子数组所有元素都要大于后面的;一般在有序排列中查找某个元素,首先想到的是二分查找法,时间复杂度为O(logN)。

2、采用二分查找,找到数组的中间元素middle,针对题意进行分析
1)、如果中间元素middle大于第一个元素(说明前面已经排序),最小元素肯定位于middle的后面,将low指向中间元素middle,在后面的子数组中继续查找。
2)、如果中间元素middle小于第一个元素,同样可以肯定最小元素位于middle的前面,将high指向中间元素middle,在前面的子数组中继续查找。

3、问题关键是找到循环的结束条件,按照上述方式,low指向的子数组元素肯定大于high指向的子数组元素,最终low会指向前面数组的最后一个元素,high会指向后面数组的第一个元素,最终会指向两个相邻的元素,此时high指向的元素就是最小的元素,循环结束。

参考代码:
/*************************************************
Copyright:牛客网在线编程《剑指offer》
Author:zhouyuan
Date:2017-02-24
Description:旋转数组的最小数字
**************************************************/

#include <vector>
using namespace std;

class Solution {
public:
	int minNumberInRotateArray(vector<int> rotateArray) {
		if (rotateArray.empty()) {
			return 0;
		}

		int low = 0;
		int high = rotateArray.size() - 1;
		int middle = 0;
		if (rotateArray.at(low) < rotateArray.at(high)) { //说明已经是非递减排序,直接返回第一个最小元素
			return rotateArray.at(low);
		}

		//二分查找
		while (low < high) {
			if (high - low == 1) {
				middle = high;
				break;
			}

			int middle = (low + high) / 2;
			if (rotateArray.at(middle) >= rotateArray.at(low)) {
				low = middle;
			}
			else if (rotateArray.at(middle) <= rotateArray.at(low)) {
				high = middle;
			}
		}
		
		return rotateArray.at(middle);
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值