JS Leetcode 154. 寻找旋转排序数组中的最小值 II 题解分析
壹 ❀ 引
早在10个月前,也就是去年,我记录了JS leetcode 寻找旋转排序数组中的最小值 题解分析,你不得不了解的二分法一题,那么这篇文章记录它的升级版,来自LeetCode154. 寻找旋转排序数组中的最小值 II,但是我现在回头看之前这篇文章,解题思路更像是找规律,有点难以记忆。我在前几天记录的另外两篇旋转数组中使用了相同的解题思路,所以为了思路上的统一,我想用相同的思路先把153. 寻找旋转排序数组中的最小值先重新梳理一遍,再来看它的升级版。回归正题,154. 寻找旋转排序数组中的最小值 II题目描述如下:
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
若旋转 7 次,则可以得到 [0,1,4,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 ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
示例 1:
输入:nums = [1,3,5]
输出:1
示例 2:
输入:nums = [2,2,2,0,1]
输出:0
提示:
n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转进阶:
这道题是 寻找旋转排序数组中的最小值 的延伸题目。
允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
贰 ❀ 思路分析与二分法
OK,我们还是先重新复习下153. 寻找旋转排序数组中的最小值这题,此题与升级版的题目唯一区别是数组中不存在重复项,即是一个数字不重复的被旋转的升序数组,让你找到数组中的最小值。
因为前面我们已经做了两题关于旋转数组的题目,已经总结出了一种二分法的思路,这里直接再次套用这种解题思路,比如要找到[4,5,0,1,2,3]
中的最小值,我们依然可以用mid与nums[0]
进行比较,如果mid>=nums[0]
说明升序部分在左侧,如果mid<nums[0]
说明升序部分在右侧,我们用图画出来,感受下这个规律:
图1
如上图,通过中间数mid与nums[0]
的大小比较就能知道升序在哪一边。如果升序在这一边,那么最小值一定在不是升序的这一边,看图自己感受下。当然有个特例,数组没旋转的情况下,也满足mid>=nums[0]
,但最小值其实在左侧,没关系,因为只有未旋转的数组nums[0]<=nums[length-1]
,比如:
let arr = [1];
arr[0]<=arr[arr.length-1]; //true
let arr = [1,2]
arr[0]<=arr[arr.length-1]; //true
让我们来实现这段代码:
var findMin = function (nums) {
let n = nums.length;
let l = 0;
let r = n - 1;
// 数组未旋转或者数组只有一位的情况
if (nums[l] <= nums[r]) {
return [nums[l]];
};
// 能走到这,说明数组一定旋转了
while (l < r) {
let mid = Math.floor((l + r) / 2);
// 如果mid>=nums[0],升序在左侧,最小在右侧,修改l的指针
if (nums[mid] >= nums[0]) {
// 为什么要加1,请看图感受
l = mid+1;
} else {
//反之升序在右侧,最小值在左侧,修改r指针
r = mid;
}
}
return nums[l] <= nums[r] ? nums[l] : nums[r];
};
我们来解释下这段代码中的几个注意点,第一个问题,为什么是nums[mid] >= nums[0]
,因为我们取mid是向下取整,比如数组[2,1]
,mid取的其实是nums[0]
也就是2,因为nums[mid]
其实等于nums[0]
,其实就是为了兼容这种情况。
第二个问题,为什么l=mid+1
,而r
不是mid-1
呢?其实看我们上面列举的旋转的数组图示,你会发现当mid>=nums[0]
时,由于升序在左侧,最小值在右侧,而且最小一定不可能是mid,所以直接mid+1
,不然假设数组是[2,1]
的情况,你会发现由于l=mid
会一直等于0,然后陷入死循环。
而l
不是mid-1
看图其实也很清楚,因为有可能mid就是最小值,所以我们不能舍弃掉,这也算是画图找规律的一种,但整体思路其实还是与之前两道题相同。
OK,那么到这里我们用之前mid与nums[0]
比较的思路,重新把这道题解了下,算是把思路给统一了,不然一道题一个思路也确实难以记忆。
那么回到它的升级版,也就是存在重复数的情况,我们甚至可以暴力点,直接数组去重后套用上面的代码,比如:
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function (nums) {
// 去重
nums = [...new Set(nums)]
// 下面不变
let n = nums.length;
let l = 0;
let r = n - 1;
// 数组未旋转或者数组只有一位的情况
if (nums[l] <= nums[r]) {
return [nums[l]];
};
// 能走到这,说明数组一定旋转了
while (l < r) {
let mid = Math.floor((l + r) / 2);
// 如果mid>=nums[0],升序在左侧,最小在右侧,修改l的指针
if (nums[mid] >= nums[0]) {
// 为什么要加1,请看图感受
l = mid+1;
} else {
//反之升序在右侧,最小值在左侧,修改r指针
r = mid;
}
}
return nums[l] <= nums[r] ? nums[l] : nums[r];
};
当然既然题目都给了重复数字,咱们直接去重多少差点意思,如果不去重我们如何解决这道题呢?
举个例子,假设数组为[3,1,3]
,上面的代码会直接挂掉,因为一开始就满足了nums[l] <= nums[r]
,其实在JS Leetcode 81. 搜索旋转排序数组 II 题解,补救二分法的可行性中,我们就解释了重复元素导致二分法特性丢失的问题,而挽救这种特性的办法就是,当数组的nums[l]===nums[r]
时,我让任意一方的指针进行缩进,比如r++
即可,因为给无数个3和给一个3,并不会影响到最终的结果判断。
所以我们修改下上方的代码,不用去重就是这样:
var findMin = function (nums) {
let n = nums.length;
let l = 0;
let r = n - 1;
while (l < r) {
// 只要左右指针相同,就让r--,比如[3,1,3]就会变成[3,1]
if (nums[l] <= nums[r]) {
return [nums[l]];
};
// 这个移进来了,如果放外面可能有[3,1,3]这种,同时也用于解决1个元素的情况以及未旋转的情况
if (nums[l] === nums[r]) {
r--;
break;
};
let mid = Math.floor((l + r) / 2);
// 如果mid>=nums[0],升序在左侧,最小在右侧,修改l的指针
if (nums[mid] >= nums[0]) {
// 为什么要加1,请看图感受
l = mid + 1;
} else {
//反之升序在右侧,最小值在左侧,修改r指针
r = mid;
}
}
return nums[l] <= nums[r] ? nums[l] : nums[r];
};
那么本文就到这里了,相关系列题型可见下方。
JS leetcode 153. 寻找旋转排序数组中的最小值 题解分析,你不得不了解的二分法
JS Leetcode 33. 搜索旋转排序数组题解,图解旋转数组中的二分法
JS Leetcode 81. 搜索旋转排序数组 II 题解,补救二分法的可行性
JS Leetcode 154. 寻找旋转排序数组中的最小值 II 题解分析的更多相关文章
- Java实现 LeetCode 154 寻找旋转排序数组中的最小值 II(二)
154. 寻找旋转排序数组中的最小值 II 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找 ...
- [LeetCode] 154. 寻找旋转排序数组中的最小值 II
题目链接 : https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ 题目描述: 假设按照升序排序的数组在预 ...
- Leetcode之二分法专题-154. 寻找旋转排序数组中的最小值 II(Find Minimum in Rotated Sorted Array II)
Leetcode之二分法专题-154. 寻找旋转排序数组中的最小值 II(Find Minimum in Rotated Sorted Array II) 假设按照升序排序的数组在预先未知的某个点上进 ...
- 154寻找旋转排序数组中的最小值II
title: 寻找旋转排序数组中的最小值II 题目描述 题目链接:寻找旋转排序数组中的最小值II 解题思路 和上题同理:数组特点有 nums[mid] < nums[right],最小值肯定在m ...
- 领扣(LeetCode)寻找旋转排序数组中的最小值 个人题解
假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中最小的元素. 你可以假设数组中不存在重 ...
- 154. 寻找旋转排序数组中的最小值 II
转跳点:--\(˙<>˙)/-- 原本打算大年三十十一起写完的,结果这篇拖到了年初一…… 这道题比刚刚那道,麻烦一点,因为有重复,所以我们需要考虑重复的情况,就是刚刚的两种情况变成了三种: ...
- LeetCode154.寻找旋转排序数组中的最小值 II
154.寻找旋转排序数组中的最小值 II 描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). ...
- LeetCode:寻找旋转排序数组中的最小值【153】
LeetCode:寻找旋转排序数组中的最小值[153] 题目描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0 ...
- lintcode:寻找旋转排序数组中的最小值 II
寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在重复的元 ...
- Java实现 LeetCode 153 寻找旋转排序数组中的最小值
153. 寻找旋转排序数组中的最小值 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中 ...
随机推荐
- go Print 和 反射
0. 前言 在 小白学标准库之反射 reflect 篇中介绍了反射的三大法则.但并未给出具体示例介绍反射,感觉还是少了点什么.这里进一步通过fmt.Println 源码,查看反射如何使用的,算是对前文 ...
- Chrome 控制台 换行编写js调试代码
转载请注明出处: 在 chrome 浏览器的console 控制台编写 js 调试或验证代码时,每输一行换行时,就会执行当前行的函数,再重新换行输入时,就会将之前的代码忽略,这种方式就会导致 chro ...
- 本地打包编译jdk版本问题
一.遇到的问题 进行项目接入pinpoint-ice插件,启动项目时pinpoint-agent日志报如下不支持jdk8的错误.' 二.排查 我们是在个人笔记本电脑上windows环境下通过mav ...
- WPF|黑暗模式的钱包支付仪表盘界面设计
阅读目录 效果展示 准备 简单说明 + 源码 结尾(视频及源码仓库) 1. 效果展示 欣赏效果: 2. 准备 创建一个WPF工程,比如站长使用 .NET 7 创建名为 WalletPayment 的W ...
- 【MicroPython] 用 c 添加接口 -- 添加 module
[来源]https://www.eemaker.com/micropython-add-module.html
- 2023第十四届极客大挑战 — PWN WP
WP可能有点简陋,因为是直接从docx导入到博客的,实在不想再重新写了!大家凑合着看吧!哈哈哈,问题不大! pwn方向出自:队友 nc_pwntools 只要过了chal1和chal2即可执行任意命令 ...
- Laravel - 改为国内镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ (阿里云) 或 composer ...
- Redis不同版本性能研究
Redis不同版本性能研究 背景 前期同事遇到了一个大key的慢查询. 前提条件是: 一个 60万key的环境里面. 有一个 260万元素的set类型的key 产品经常会进行 smember key ...
- [转帖]比快更快的 ELK 8 安装使用指南-Elasticsearch,Kibana,Logstash
https://juejin.cn/post/7133907643386560519 携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情 Elastic 8 ...
- 编译打包rabbitmq然后一键部署的简单方法
摘要 之前总结过一版,但是感觉不太全面 想着本次能够将使用中遇到的问题总结一下. 所以本次是第二版 介质下载 rabbitmq 不区分介质的打包文件 rabbitmq-server-generic-u ...