我是靠谱客的博主 内向早晨,最近开发中收集的这篇文章主要介绍寻找旋转排序数组中的最小值(二分法简单实现),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目

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

示例 :
输入:nums = [3,4,5,1,2]
输出:1

提示:
1、1 <= nums.length <= 5000;
2、-5000 <= nums[i] <= 5000;
3、nums 中的所有整数都是 唯一 的;
4、nums 原来是一个升序排序的数组,但在预先未知的某个点上进行了旋转。

注意点

1、因为数组大部分有序,所以我们可以使用二分法寻找最小的元素;
2、二分法边界问题:

  • 当left = 0,right = nums.length - 1时,循环判断条件为 left <= right;因为 left 和 right 都必须取到,即 [left,right] ,所以当left = right 时也需要判断;
  • 当left = 0,right = nums.length时,循环判断条件为 left < right;因为 left 必须取到,但 right 不需要取到,即 [left,right), 所以当left = right 时不需要判断。

3、二分法可能出现的问题:使用二分法切割以上数组一定出现至少一半是有序的(当旋转点与中间点一样时,两边都是有序的;当当旋转点与中间点不一样时,一边有序,一边无序)

  • 左边有序,右边有序;(直接比较返回最小值)
  • 左边有序,右边无序;(记录有序的最小值,二分法继续寻找另一半数组的最小值)
  • 左边无序,右边有序。(记录有序的最小值,二分法继续寻找另一半数组的最小值)

实现

class Solution {
public int findMin(int[] nums) {
// 左边界
int left = 0;
// 有边界
int right = nums.length - 1;
// 记录有序部分的最小值,默认为nums[0]
int result = nums[0];
// 二分法寻找最小值
while (left <= right) {
// 计算中间点
int mid = left + (right - left) / 2;
// 左边有序的情况
if (nums[left] <= nums[mid]) {
// 更新有序数组的最小值
result = Math.min(result, nums[left]);
// 左边有序,右边有序的情况
if (nums[mid] <= nums[right]) {
// 直接返回最小值
return Math.min(result, nums[mid]);
}
// 左边有序, 右边无序的情况(继续寻找)
left = mid + 1;
// 左边无序的情况
} else {
// 更新有序数组的最小值
result = Math.min(result, nums[mid]);
// 左边无序, 右边有序的情况(继续寻找)
right = mid - 1;
}
}
// 当nums.length == 1时,返回nums[0]
return result;
}
}

最后

以上就是内向早晨为你收集整理的寻找旋转排序数组中的最小值(二分法简单实现)的全部内容,希望文章能够帮你解决寻找旋转排序数组中的最小值(二分法简单实现)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部