题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
使用【二分法】
mid = low + (high - low)/2
需要考虑三种情况:
(1)array[mid] > array[high]:
出现这种情况的 array 类似[3,4,5,6,0,1,2],此时最小数字一定在 mid 的右边。
low = mid + 1
(2)array[mid] == array[high]:
出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边还是右边,这时只好一个一个试,
high = high - 1
(3)array[mid] < array[high]:
出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是 array[mid] 或者在 mid 的左边。因为右边必然都是递增的。
high = mid
注意点:
如果待查询的范围最后只剩两个数,那么 mid 一定会指向下标靠前的数字
比如 array = [4,6];
array[low] = 4 ;
array[mid] = 4 ;
array[high] = 6 ;
如果 high = mid - 1,就会产生错误, 因此 high = mid,
但第(1)种情况中 low = mid + 1 就不会错误。
代码:
package 旋转数组的最小数字;
import java.util.concurrent.atomic.DoubleAdder;
/**
* 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。
* 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
* NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
*/
class Solution {
// 采用二分查找法
/**
* @param 非减排序的数组的一个旋转
* @return 数组最小值,int 类型
*/
public static int minNumberInrotateArray(int[] array) {
int len = array.length; // 获取数组长度,判断数组是否为空
if (len == 0) {
return 0;
}
int low = 0,high = len - 1; // 定义数组的第一个、最后一个元素,从而得出中间的元素
int mid = (low + high) / 2;
while (low < high) { // 数组长度大于 1 时才进行运算
if (array[mid] > array[high]) { // 情况1:array[mid] > array[high],此时【最小值】在 mid 右边
low = mid + 1;
}else if (array[mid] == array[high]) { // 情况2:array[mid] == array[high],此时不好判断【最小值】位置,逐个尝试
high = high - 1;
}else { // 情况3:array[mid] < array[high],此时【最小值】是 mid 或者在 mid 左边
high = mid; // 当数组只剩下两个元素时,mid 指向 low,若 high = mid - 1,会下标越界
}
return array[low];
}
return array[low];
}
}
public class Demo {
public static void main(String[] args) {
Solution solution = new Solution();
int[] array = { 3, 4, 5, 0, 1, 2 };
System.out.println(solution.minNumberInrotateArray(array));
}
}