时间限制:1秒空间限制:32768K
通过比例:15.05%
最佳记录:0 ms|8552K (来自 牛客841129号)
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减序列的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
思想:采用二分法,定义low,mid,high下标。如果[mid]<[low]代表mid处于旋转过的部分中,反之处于主体部分中,特殊情况[mid]=[low]分情况考虑,这里注意[mid]>[low]有可能是旋转位数为0的情况,需要加判定。
我的代码:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int low, high, mid;
low = 0, high = rotateArray.size() - 1;
//数组为空;
if(high < 0) {
return 0;
}
//数组不为空;
//(1)数组只有一个或两个个元素;
if(low >= high - 1) {
if(rotateArray[low] < rotateArray[high]) {
return rotateArray[low];
}
else {
return rotateArray[high];
}
}
//(2)数组有三个或更多元素;
while(low < high - 1) {
//mid选择算法;
mid = (low + high)/2;
if(rotateArray[mid] > rotateArray[low]) {
//考虑旋转位数为0的情况;
if(rotateArray[mid] < rotateArray[high]) {
return rotateArray[0];
}
else {
low = mid;
}
}
else if(rotateArray[mid] < rotateArray[low]) {
high = mid;
}
else if(rotateArray[mid] == rotateArray[low]) {
if(rotateArray[mid] > rotateArray[high]) {
low = mid;
}
else if(rotateArray[mid] < rotateArray[high]) {
high = mid;
}
//特殊情况,不能判断mid归属;
else {
int num = except(rotateArray);
return num;
}
}
}
return rotateArray[low] > rotateArray[high] ? rotateArray[high] : rotateArray[low];
}
//至少有一半元素相同所以只能顺序遍历;
private:
int except(vector<int> rotateArray) {
vector<int>::iterator it;
int min;
for(it = rotateArray.begin(); it != rotateArray.end(); it++) {
if(it == rotateArray.begin()) {
min = * it;
}
else {
min = min <= *it ? min : *it;
}
}
return min;
}
};
如果数组较小直接遍历
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size() == 0) {
return 0;
}
else if(rotateArray.size() == 1) {
return rotateArray[0];
}
return except(rotateArray);
};
在牛客网讨论区看到一个更简洁的代码,利用迭代器,省去了下标,看起来更加简洁,思想是当[mid]=[low]时将low自加一就行了,省去了繁琐的特殊情况考虑。
代码:
int minNumberInRotateArray(vector<int> rotateArray) {
size_t len = rotateArray.size();
if(len == 0)
return 0;
if(len == 1)
return rotateArray[0];
vector<int>::iterator low = rotateArray.begin();
vector<int>::iterator mid;
vector<int>::iterator high = rotateArray.end();
while(low <= high)
{
//防止迭代器失效
mid = low + (high - low)/2;
if(*mid >*high)
{
low = mid + 1;
}
else if(*mid < *high)
{
high = mid;
}
else
{
high = high-1;
}
if(low >= high)
{
break;
}
}
return *low;
}
//防止迭代器失效这句我的理解是防止直接low + high造成地址空间溢出。