剑指offer_5_6_旋转数组

旋转数组最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{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)

​ 情况二:

扫描二维码关注公众号,回复: 10012605 查看本文章

记当前的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;
    }
}
发布了63 篇原创文章 · 获赞 1 · 访问量 4126

猜你喜欢

转载自blog.csdn.net/chenhanhao0000/article/details/104056299