力扣153 Find Min In Rotated Sorted Array 在旋转数组中寻找最小值 medium 20220125 题目描述: * 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到: * 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] * 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7] * 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。 * 给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 * 示例: * 输入:nums = [3,4,5,1,2] * 输出:1 * 解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。 思路: * 多次翻转后,输入的数组是多段不连续的升序数组,采用二分查找,每次拿mid值与目标值比较, * 如果目标值比mid值小,那么对该部分再次二分以此类推,不断缩小区间,最后只剩下2个相邻的数,取最小的那个。 * 至于目标值为什么选择最后一个: * 0 1 2 3 4 5 6 7 是从最后一位7向前翻转, * 4 5 6 7 0 1 2 / 1 2 4 5 6 7 0 如果mid>target,说明第一位数也就是最小值还没开始翻,最小值在右侧, * 0 1 2 4 5 6 7 / 7 0 1 2 4 5 6 如果mid<target,说明最小值已经翻了,最小值在左侧
方法1:二分法
public class FindMinInRotatedSortedArray {
//1.选择最后一个数作target
public int findMin(int[] nums){
//1.边界条件
if (nums==null||nums.length==0) return -1;
//2.初始化start end target
int start=0;
int end=nums.length-1;
int target=nums[end];
//3.开始循环二分,mid值与目标值比较决定选哪一边
while(start+1<end){
int mid=start+(end-start)/2;
if (nums[mid]>target) start=mid;
else end=mid;
}
//4.最后只剩下两个相邻的数,其中一个就是最小的
return Math.min(nums[start],nums[end]);
}
public static void main(String[] args) {
FindMinInRotatedSortedArray find = new FindMinInRotatedSortedArray();
int[] arr={7,0,1,2,4,5,6};
System.out.println(find.findMin(arr));
}
}
方法二:直接遍历
public int findMin2(int[] nums){
int min=nums[0];
for (int num : nums) {
if (num<min) min=num;
}
return min;
}
方法三:stream流中的min函数
public int findMin3(int[] nums){
int min = Arrays.stream(nums).min().getAsInt();
return min;
}