704. 二分查找
左闭右闭区间,middle取中间值向下取整
function search(nums: number[], target: number): number {
let l = 0
let r = nums.length - 1
while (l <= r) {
const m = l + Math.floor((r - l) / 2)
if (nums[m] === target) {
return m
} else if (nums[m] > target) {
r = m - 1
} else {
l = m + 1
}
}
return -1
};
27. 移除元素
快慢指针,慢指针用来放置非val元素,快指针遍历数组
function removeElement(nums: number[], val: number): number {
let s = 0
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== val) {
nums[s] = nums[i]
s++
}
}
return s
};
35. 搜索插入位置
先处理最左边和最右边两种边界情况,剩下一种插入中间的情况时,插入位置一定是l,因为此时l>r,l在m的右边
function searchInsert(nums: number[], target: number): number {
let l = 0
let r = nums.length - 1
if (target < nums[l]) {
return 0
} else if (target > nums[r]) {
return r + 1
}
while (l <= r) {
const m = l + Math.floor((r - l) / 2)
if (nums[m] === target) {
return m
} else if (nums[m] > target) {
r = m - 1
} else {
l = m + 1
}
}
return l
};
34. 在排序数组中查找元素的第一个和最后一个位置
两次二分查找,第一次找第一个元素的位置,第二次找最后一个元素的位置,找第一个就是不停缩小r,找最后一个就是不停缩小l
function searchRange(nums: number[], target: number): number[] {
let first = -1
let last = -1
let l = 0
let r = nums.length - 1
while (l <= r) {
const m = l + Math.floor((r - l) / 2)
if (nums[m] === target) {
first = m
r = m - 1 // 重点
} else if (nums[m] > target) {
r = m - 1
} else {
l = m + 1
}
}
l = 0
r = nums.length - 1
while (l <= r) {
const m = l + Math.floor((r - l) / 2)
if (nums[m] === target) {
last = m
l = m + 1 // 重点
} else if (nums[m] > target) {
r = m - 1
} else {
l = m + 1
}
}
return [first, last]
};