二分查找
题目
视频链接
手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
思路
左闭右闭写法
左闭右闭的区间,也就是[left,right],区间里的数是有意义的:
- left 初始化为0,right 初始化为
nums.length -1,都符合在区间内 - 左闭右闭时,left = right 有意义,所以判断条件为left <= right
- 如果nums[middle] < target,当前target一定不是nums[middle],区间为[middle + 1,right]
- 如果nums[middle] > target,当前target一定不是nums[middle],区间为[left,middle - 1]
var search = function(nums, target) {
let left = 0;
let right = nums.length -1;
while(left <= right){
const middle = Math.floor((left+right)/2);
if(nums[middle] < target){
left = middle + 1;
}else if(nums[middle] > target){
right = middle - 1;
}else {
return middle;
}
}
return -1;
};
左闭右开写法
左闭右开的区间,也就是[left,right),区间里的数是有意义的:
- left 初始化为0,right 初始化为
nums.length,符合在区间内 - 左闭右开时,left = right 无意义,所以判断条件为left < right
- 如果nums[middle] < target,当前target一定不是nums[middle],区间为[middle + 1,right)
- 如果nums[middle] > target,right的值为middle,因为当前区间为左闭右开,right为niddle时,下一个区间不会查找nums[middle]。
var search = function(nums, target) {
let left = 0;
let right = nums.length;
while(left < right){
const middle = Math.floor((left+right)/2);
if(nums[middle] < target){
left = middle + 1;
}else if(nums[middle] > target){
right = middle;
}else {
return middle;
}
}
return -1;
};
#
移除数组元素
题目
视频链接
数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
思路
暴力法
var removeElement = function(nums, val) {
for(let i=0;i<nums.length;i++){
if(nums[i] === val){
for(let j=i;j<nums.length - 1;j++){
nums[j] = nums[j+1]
}
// i重新回到当前元素
i--;
// 长度变短了
nums.length--;
}
}
};
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
双指针
定义两个指针:
- 快指针指向新数组所需要的元素
- 慢指针新数组中对应元素需要更新到的位置
如果nums[fast]等于需要删除的元素,快指针移动,慢指针不移动,因为慢指针的位置需要更新为快指针对应的元素。
var removeElement = function(nums, val) {
let fast = 0;
let slow = 0;
for(;fast<nums.length;fast++){
if(nums[fast] !== val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)