旋转数组最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解法一: 暴力
因为是有排列顺序的,所以依次遍历数组,一直找到比数组第一个数小的数,则为反转数组的第一个值
public int minNumberInRotateArray(int [] array) {
if(array.length==0){
return 0;
}
//找到递增数列,则后面的为反转数组,则反转数组第一个数为该数组最小值
int temp = array[0];
int i = 0;
while(temp<=array[i] && i<array.length){
i++;
}
return array[i];
}
解法二: 二分法
-
注意
由于是非递减,我们不可以明确知道最小值应该往那一边收缩,例如{1,2,3,4,5} ---> {3,4,5,1,2}
-
分析应该从那一边收缩
有两种情况
- 情况一: 数组没有发生旋转
- 情况二:数组发生了旋转
情况一:
数组没有发生旋转时,则数组最左边的数(left) 一定是小于数组最右边的数
遇到这种情况,直接返回(left)
情况二:
记当前的mid(中间值)为n
-
当n的值小于下标为n-1的值,则n一定是最小数
-
当n的值比arr[0](数组第一个数大时),则说明从0-n这一段是顺序的,需要检索n+1-end部分
import java.util.*;
public class Solution {
public int minNumberInRotateArray(int [] nums) {
if (nums.length == 1) {
return nums[0];
}
int l = 0;
int r = nums.length - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[l] < nums[r]) {
return nums[l];
}
if (nums[mid] > nums[mid + 1]) {
return nums[mid + 1];
}
if (nums[mid] < nums[mid - 1]) {
return nums[mid];
}
if (nums[mid] > nums[0]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return 0;
}
}
网友评论