[每日一题] 142. 寻找旋转排序数组中的最小值(数组、二分法、分治、多方法)

1. 题目来源

链接:寻找旋转排序数组中的最小值
来源:LeetCode

2. 题目说明

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [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

3. 题目解析

方法一:二分法

主要思想如下:

  • 用中间的值 nums[mid] 和右边界值 nums[right] 进行比较
  • 若数组没有旋转或者旋转点在左半段时,中间值是一定小于右边界值,所以要去左半边继续搜索,反之则去右半段查找
  • 最终返回 nums[right] 即可

参见代码如下:

// 执行用时 :12 ms, 在所有 C++ 提交中击败了42.40%的用户
// 内存消耗 :12.5 MB, 在所有 C++ 提交中击败了5.37%的用户

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[right]) 
                left = mid + 1;
            else 
                right = mid;
        }
        return nums[right];
    }
};

方法二:分治法、递归

主要思想如下:

  • 每次将区间 [start, end] 从中间 mid 位置分为两段,分别调用递归函数,并比较返回值,每次取返回值较小的那个即可

参见代码如下:

// 执行用时 :8 ms, 在所有 C++ 提交中击败了42.40%的用户
// 内存消耗 :12.7 MB, 在所有 C++ 提交中击败了5.37%的用户

class Solution {
public:
    int findMin(vector<int>& nums) {
        return helper(nums, 0, nums.size() - 1);
    }
    int helper(vector<int>& nums, int start, int end) {
        if (nums[start] <= nums[end]) 
            return nums[start];
        int mid = (start + end) / 2;
        return min(helper(nums, start, mid), helper(nums, mid + 1, end));
    }
};
发布了307 篇原创文章 · 获赞 125 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/104436861
今日推荐