6.旋转数组的最小数字
思路:
该题主要考察对二分查找的理解和应用。
- 设置左右边界,left = 0,right = arr.length - 1
- 设置while循环的判定条件,left < right
- 先判断当前数组或者子数组,是否为非递减数组,比如
1,1,3,4,5,5
这种就是非递减数组,如果是非递减数组,说明当前子数组就是旋转后的那一部分升序子数组,arr[left]就是我们所要求的结果。比如3,4,5,1,2
。如果left = 3,right = 4即此时,子数组为1,2
,为非递减数组,那么此时arr[left] = 1就是当前数组中的最小数。 mid = left + (right - left) / 2
,求出中位下标。如果采取(left+right) / 2
进行计算中位下标,left+right
可能会发生越界,超过了int类型的范围,因此采取left + (right - left) / 2
计算中位数下标,防止越界。- 接下来要考虑到三种情况:
- 若
array[left] < array[mid]
,此时是中位数mid左边有序,比如,3,4,5,1,2
, 因此移动left到mid+1的位置,left = mid+1
。 - 若
array[mid] < array[right]
,此时是中位数mid右边有序,比如,4,5,1,2,3
,因为此时mid位置可能为最小数,因此right移动到mid位置,right = mid
。 - 若都不满足,那么此时当前整个数组或者子数组为无序状态,比如
1,3,2,1,2,3,1
此时数组状态为无序,直接顺序遍历即可,left++
。
- 若
- 先判断当前数组或者子数组,是否为非递减数组,比如
- 最后返回arr[left]即可。
代码实现:
//升序数组旋转后,找到最小的数字
public class Solution{
public int minNumberInRotateArray(int[] array) {
if (array.length == 0) return 0;
//使用二分查找方法,找到有序的升序数组的开头,找到之后返回
int left = 0, right = array.length - 1;
while (left < right) {
//判断子数组是否是非递减数组,满足的话,当前子数组的left就是当前数组的最小数
if (array[left] < array[right]) return array[left];
int mid = left + (right - left) / 2;
//如果left到mid升序,left向左移到mid+1
if (array[left] < array[mid]) {
left = mid +1;
} else if (array[mid] < array[right]) { //如果mid到right升序
right = mid;
} else { //都不满足,那就是乱序,直接left++顺序遍历即可
left++;
}
}
return array[left];
}
}