algorighm/top-interview-leetcode150/binary-search/153寻找旋转排序数组中的最小值.js

56 lines
2.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @param {number[]} nums
* @return {number}
*/
const findMin = function (nums) {
};
/*
数组在某个位置旋转之后会变成两段连续的序列,并且第一段的所有值都比第二段大,我们直接使用二分查找,
如果mid落在第一段则表明我们需要往右边继续找使left = mid+1,如果落在第二段则将right=mid如果
left===right返回left所在位置的数即可就是最小的数。
*/
function f1(nums) {
let left = 0;
let right = nums.length - 1;
// 如果nums[right] > nums[left] 表明在第0个位置旋转或者说没有旋转直接返回nums[left]
if (nums[right] > nums[left]) return nums[left];
while (left < right) {
const mid = left + ((right - left) >> 1);
// 如果nums[mid]比nums[0]大则表明它落在第一段
if (nums[mid] >= nums[0]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}
/*
方法1通过判断nums[mid]是否大于nums[0],如果大于则表明落在第一段,但是[2,1]这个测试用例通不过nums[0]就是nums[mid]
自己所以还要加上等于的情况也就是说如果nums[mid] >= nums[0]的话表明落在了第一段,反之落在了第二段,这样又会产生
新的问题就是如果旋转的位置是0,也就是说整个数组没有发生旋转,那么最后会找到整个数组中最大的数,所以还要用卫语句处理,
这种方式不太好。
方法2通过判断nums[mid] > nums[right],如果大于则表明落在第一段,反之落在第二段,而且还能通过上面的测试用例,这种方式
更加的好,更符合夹逼思想。
*/
function f2(nums) {
let left = 0; let
right = nums.length - 1;
while (left < right) {
const mid = left + ((right - left) >> 1);
// 与 nums[right] 比较,更直观,逻辑更接近二分标准模型
if (nums[mid] > nums[right]) {
left = mid + 1; // 最小值在右边
} else {
right = mid; // 最小值在左边(可能是 mid
}
}
return nums[left];
}