二分搜索
在排序数组中查找元素的第一个和最后一个位置
先二分找到其中一个,再循环左右相等元素并取最左最右索引
var searchRange = function (nums, target) {
if(nums.length < 2 && nums[0]=== target) return [0,0]
if(nums.length < 2 && nums[0]!== target) return [-1,-1]
let left = 0, right = nums.length - 1, mid, ans = [-1, -1]
while (left <= right) {
mid = Math.floor((left + right) / 2)
if (target < nums[mid]) {
right = mid - 1
} else if (target > nums[mid]) {
left = mid + 1
} else {
ans = [mid, mid]
let temp = mid
while (nums[temp-1] === target) {
temp -= 1
}
while (nums[mid+1] === target) {
mid += 1
}
ans = [temp, mid]
return ans
}
}
return ans
};
搜索旋转排序数组
二分思想,每次if找顺序没乱的那边先进行位移
var search = function (nums, target) {
let n = nums.length
if (n === 0) return -1
if (n === 1) return target === nums[0] ? 0 : -1
let left = 0, right = n - 1, mid;
while (left <= right) {
mid = Math.floor((left + right) / 2)
if (target === nums[mid]) {
return mid
} else {
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
right = mid - 1
} else {
left = mid + 1
}
} else {
if (target <= nums[n - 1] && target > nums[mid]) {
left = mid + 1
} else {
right = mid - 1
}
}
}
}
return -1
};
搜索二维矩阵
var searchMatrix = function (matrix, target) {
let m = matrix.length, n = matrix[0].length;
let left = 0, right = n - 1, row = 0
while (!(target >= matrix[row][left] && target <= matrix[row][right])){
row++
if(row > m-1) return false
}
if(n === 1) return matrix[row][0] === target
let mid
while(left <= right){
mid = Math.floor((left+right)/2)
if(target === matrix[row][mid]){
return true
}else if(target < matrix[row][mid]){
right = mid - 1
}else{
left = mid + 1
}
}
return false
};
寻找旋转排序数组中的最小值
var findMin = function(nums) {
let left = 0, right = nums.length, mid, ans = nums[0]
while(left < right){
mid = Math.floor((left+right)/2)
if(nums[mid]<ans){
ans = nums[mid]
}
if(nums[0] < nums[mid]){
left = mid + 1
}else{
right = mid
}
}
return ans
};
寻找峰值
var findPeakElement = function(nums) {
const n = nums.length;
let left = 0, right = n - 1, ans = -1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (compare(nums, mid - 1, mid) < 0 && compare(nums, mid, mid + 1) > 0) {
ans = mid;
break;
}
if (compare(nums, mid, mid + 1) < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return ans;
}
// 辅助函数,输入下标 i,返回一个二元组 (0/1, nums[i])
// 方便处理 nums[-1] 以及 nums[n] 的边界情况
const get = (nums, idx) => {
if (idx === -1 || idx === nums.length) {
return [0, 0];
}
return [1, nums[idx]];
}
// idx1取值大放回1,idx2大返回-1,并且处理好边界问题
const compare = (nums, idx1, idx2) => {
const num1 = get(nums, idx1);
const num2 = get(nums, idx2);
if (num1[0] !== num2[0]) {
return num1[0] > num2[0] ? 1 : -1;
}
if (num1[1] === num2[1]) {
return 0;
}
return num1[1] > num2[1] ? 1 : -1;
}