知识点:数组、二分查找
一、题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
二、解题思路:
1:暴力解法:初始化最小值为旋转数组的第一个元素,然后遍历数组,并比较大小,遍历完后便可找到最小值。
C++:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {//输入的数组是原数组的旋转数组,原数组是个非递减排序的数组
//遍历数组元素,逐个比较大小,最后找到最小值
int len = rotateArray.size();
if (len == 0){
return 0;
}
int min = rotateArray[0];//初始化最小值为数组的第一个元素
for(int i=1; i<len; i++){
if(min > rotateArray[i]){
min = rotateArray[i];
}
}
return min;
}
};
python2.7.3:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
length = len(rotateArray)
if length==0:
return 0
min_val = rotateArray[0]
for val in rotateArray:
if val < min_val:
min_val = val
return min_val
2:旋转数组的特点:旋转后前面是个递增的子序列,后面也是个递增的子序列,中间的那个元素就是最小值,所以遍历数组,依次比较前后两个元素大小。
c++:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int length = rotateArray.size();
if(length == 0){
return 0;
}
for(int i=0; i<length; i++){
if(rotateArray[i] > rotateArray[i+1]){
return rotateArray[i+1];
}else{
continue;
}
}
}
};
python2.7:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
length = len(rotateArray)
if length == 0:
return 0
for i in range(length):
if rotateArray[i] > rotateArray[i+1]:
return rotateArray[i+1]
else:
continue
3:二分法查找:设置两个指针pre和last,分别指向旋转数组的第一个元素和最后一个元素,然后求出中间元素。先比较中间元素与最后一个元素的大小,若中间元素大于最后一个元素,说明最小值在区间[mid,last]之间,更新pre指针,pre = mid+1; 若中间元素小于最后一个元素,则说明最小值在区间[pre,mid]之间,但中间元素也可能是最小值,更新last指针,last = mid,而不是mid-1。
非递减排序,也有可能中间元素和最后一个元素相等,此时更新last,last = last-1。
C++:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int length = rotateArray.size();
if (length == 0)
return 0;
int pre = 0;//第一个元素下标
int last = length - 1;//最后一个元素下标
while (pre < last){
int mid = (pre + last) / 2;
//case1:当中间元素 大于 最后一个元素,说明最小值在右半区间,则更新pre
if (rotateArray[mid] > rotateArray[last]){
pre = mid + 1;
}
//case2:当中间元素小于最后一个元素,说明最小值在左半区间
//但是中间这个元素,可能就是最小值,因此是 last=mide,而不是一般的last=mid-1
else if (rotateArray[mid] < rotateArray[last]){
last = mid;
}
//case3://当中间元素 等于 最后一个元素,说明有重复元素,将区间缩小一个
else {
last = last - 1;
}
}
return rotateArray[pre];
}
};
python2.7:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
length = len(rotateArray)
begin,end = 0,length-1
while begin < end:
mid = (begin + end) // 2
if rotateArray[mid] > rotateArray[end]:
begin = mid + 1
elif rotateArray[mid] < rotateArray[end]:
end = mid
else:
end -= 1
return rotateArray[begin]