【剑指offer】2.4.2 查找和排序
作者:互联网
面试题11:旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
解答:和二分查找一样,我们用两个指针分别指向数组的第一个元素和最后一个元素。接着找到数组中间的元素。如果该中间元素大于或者等于第一个指针指向的元素,说明此时数组中最小的元素应该位于该中间元素的后面,可以把第一个指针指向该中间元素,从而缩小查找范围。
同样,如果中间元素小于或者等于第二个指针指向的元素,则说明此时数组中最小的元素应该位于该中间元素的前面,可以把第二个指针指向该中间元素,从而缩小查找范围。
以此循环下去,最终第一个指针将指向前面子数组的最后一个元素,而第二个指针会指向后面子数组的第一个元素。也就是它们最终会指向两个相邻的元素,而第二个指针指向的刚好是最小的元素。
还有一种特殊的情况,就是当两个指针指向的数字及它们中间的数字三者相同的时候,我们无法判断中间的数字是位于前面的子数组还是后面的子数组,也就无法移动两个指针来缩小查找的范围。此时不得不采用顺序查找的办法。实现代码如下:
int MidInOrder(vector<int> rotateArray)
{
if(rotateArray.size() == 0)
{
throw new std::exception("Invalid parameters");
}
int len = rotateArray.size();
int result = rotateArray[0];
for(int i = 1;i < len;i++)
{
if(result > rotateArray[i])
{
result = rotateArray[i];
}
}
return result;
}
int minNumberInRotateArray(vector<int> rotateArray)
{
if(rotateArray.size() == 0)
{
throw new std::exception("Invalid parameters");
}
int left = 0;
int right = rotateArray.size() - 1;
int mid = left;//初始化为第一个元素,若数组本身有序,可直接返回
while(rotateArray[left] >= rotateArray[right])//若用left<right作为判断条件则会陷入死循环
{
if(right - left == 1)
{
mid = right;
break;
}
mid = ((right - left) >> 1) + left;
//若三数相等只能遍历
if(rotateArray[left] == rotateArray[mid]
&& rotateArray[mid] == rotateArray[right])
{
return MidInOrder(rotateArray);
}
if(rotateArray[mid] >= rotateArray[left])
{
left = mid;
}
else
{
right = mid;
}
}
return rotateArray[mid];
}
标签:offer,int,元素,指针,查找,数组,left,2.4,rotateArray 来源: https://blog.csdn.net/PinkBananA_/article/details/94134355