153. 寻找旋转排序数组中的最小值(2020-02-11)

链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array

题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:

输入: [3,4,5,1,2]
输出: 1

示例 2:

输入: [4,5,6,7,0,1,2]
输出: 0

思路解析

  1. (升序)排序的数组进行查找操作,采用二分查找
  2. 此题的有序是进行了一定变形的(旋转),关键是确定向前规约还是向后规约
    • nums[mid]是最小的时候跳出循环:
    1. 不在数组的开头或者结尾的时候,需要比前面的元素小(此时无需比后面的元素小,因为除去在旋转点处,任意元素都比后面相邻的元素小)
    2. 在开头时,nums[mid]nums[mid]
    3. 在结尾时,nums[mid]nums[mid]
    • nums[mid]>nums[0]或者nums[mid]时,向前规约
    • nums[mid]或者nums[mid]>nums[nums.length]时,向后规约
  3. 考虑仅有一个元素的情况,nums[0]==nums[nums.length]可以整合到mid在开头或者结尾的情况中
  4. 考虑数组元素整体有序的情况(即旋转无效),适合当前算法
  1. 所有变化点左侧元素 > 数组第一个元素
    所有变化点右侧元素 < 数组第一个元素

附代码

class Solution {
    public int findMin(int[] nums) {
        int len = nums.length - 1;
        int start = 0;
        int end = len;
        int mid;
        while(start <= end) {
            mid = start + (end - start) / 2; 
            if(mid == 0 && nums[0] <= nums[len] || mid == len && nums[mid] < nums[0]) {
                return nums[mid];
            }
            else if(mid != 0 && mid != len && nums[mid] < nums[mid - 1]) {
                return nums[mid];
            }
            else if(nums[mid] < nums[len]) {
                end = mid - 1;
            }
            else {
                start = mid + 1;
            }
        }
        return -1;
    }
}

tips

可以注意到代码中对于第一个判断if(mid == 0 && nums[0] <= nums[len] || mid == len && nums[mid] < nums[0])中,出现了对于nums[0]==nums[len]的判断,包含了对于数组仅有一个元素的考虑

相似题目

33.搜索旋转排序数组

你可能感兴趣的:(153. 寻找旋转排序数组中的最小值(2020-02-11))