二分查找
本质就是每次取半查找。通过比较中间值和目标值来确定查找范围。当比较的范围为空时停止。
局限性:得是有序数组
简单的二分查找
- 数组中没有重复元素
- 注意边界判断 --- 左闭右闭 左闭右开
leetcode 704
// 左闭右闭
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let left = 0
let right = nums.length - 1
while(left <= right){
let mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid +1
}else if(nums[mid] > target){
right = mid -1
}else{
return mid
}
}
return -1
};
//左闭右开
var search = function(nums, target) {
let left = 0
let right = nums.length
while(left < right){
let mid = left + ((right - left) >> 1);
if(nums[mid] < target){
left = mid +1
}else if(nums[mid] > target){
right = mid
}else{
return mid
}
}
return -1
};
tips:
-
为什么取中值要这样写 let mid = left + ((right - left) >> 1)?
越界问题,计算机的整数型也有max值,如果right+left超过(虽然不太可能),结果可能会不准确。
-
左闭右闭和左闭右开有啥区别?
左闭右闭的时候,是合法区间,里面还是有元素的,所以还是要进行循环。
左闭右开的时候,left和right相等的话,是不合法区间。
leetcode 27
// 快慢指针
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let k =0;
for(let i =0;i<nums.length;i++){
if(nums[i] !== val){
nums[k] = nums[i]
k++
}
}
return k
};
好吧...自己写的时候也并没有意识到这是双指针。 将不是目标的元素移到最前面。