大家好今天给大家分享下一道 LeetCode 中等难度 的题目[寻找旋转排序数组中的最小值](leetcode-cn.com/problems/co…)
这里主要是分享思路和注释,供大家更好的理解题目解法,代码部分是参考LeetCode 转写成javascript 代码,
题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] 若旋转 7 次,则可以得到 [0,1,2,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 = [3,4,5,1,2] 输出:1 解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。 示例 2: 输入:nums = [4,5,6,7,0,1,2] 输出:0 解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。 示例 3: 输入:nums = [11,13,15,17] 输出:11 解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
分析
1.升序排序后的旋转数组,想到了二分查找
2.只有数组选择后,那么最小值一定在不是升序数组的那一方,
除非数组从左到右都是升序数列
3.因为元素不重复 所以不需要去重
这里方法有2种(自己命名 比较丑陋见谅)
1.二分查找,升序法
2.二分查找,对照第一个元素法
解法一 :二分查找,升序法(利用数组升序的特征寻找最小值)
思路
1.数组从左到右为升序则直接终止返回第一个元素nums[l]
2.如果nums[l]===nums[r]因为没有重复元素,则说明只有数组只有一个元素,也返回Nums[l]
3.如果数组nums[l]>nums[r]说明数组中存在无序数组,则利用二分法查找
*/
var findMin = function (nums) {
let l = 0;
let r = nums.length - 1;
while (l <= r) {
// 如果是升序 或者是Nums[l]等于nums[r],则直接返回nums[l]
if (nums[l] <= nums[r]) {
return nums[l];
}
// 如果数组中存在无序数组则,则通过二分查找缩小范围
const mid = Math.floor(l + (r - l) / 2);
if (nums[l] > nums[mid]) {
// 注意因为最小索引存在在无序数组中,所以这里不能是r=mid-1 否则会错过答案
r = mid;
} else {
// 如果是有序数组 则 直接l=mid+1 缩小范围
l = mid + 1;
}
}
};
/* 复杂度
时间 O(logn)
空间 O(1)
*/
(图片来自leetcode)
解法二: 二分查找,对照第一个元素法
思路
1.如果是有序或者是相对这直接返回nums[l]
2.如果数组中存在无序数组则最小元素的左边一定是大于第一个元素,
右边一定是小于第一个元素
*/
var findMin = function (nums) {
let l = 0;
let r = nums.length - 1;
if (nums[l] <= nums[r]) {
return nums[l];
}
/* 这里不能加=,因为当l=r的时候说明数组只有一个元素,如果这个元素比nums[0]小,
就会变成无线循环 */
while (l < r) {
// 如果从左到右都是升序 则直接返回l
const mid = Math.floor(l + (r - l) / 2);
if (nums[0] > nums[mid]) {
// 这里和上题一样只能是r=mid 不然会错过答案
r = mid;
} else {
// 缩小区间到右边
l = mid + 1;
}
}
return nums[l];
};
/* 复杂度
时间 O(logn)
空间 O(1)
*/
(图片截取leetCode)
总结
这道题 ,考察的还是大家对二分查找,和旋转数组的理解,大家多多练习多多理解,就能掌握要领。
大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com