题目一 704. 二分查找
思路
经典二分查找,简单但易错,需要注意边界,设定一个统一的规则,左闭右开的区间规则进行遍历。
var search = function(nums, target) {
if (!nums) {
return -1;
}
let i = 0;
let j = nums.length;
while (i < j) {
let mid = Math.floor((j + i) / 2);
let val = nums[mid];
if (target == val) {
return mid;
} else if (target < val) {
j = mid
} else {
i = mid + 1
}
}
return -1
};
// 8.28
var search = function(nums, target) {
let left = 0;
let right = nums.length;
while (left < right) {
let mid = parseInt((right - left) / 2, 10) + left;
if (nums[mid] === target) {
return mid;
}
if (target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
};
题目2: 27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路
这个题一种是暴力解法
// 暴力解法
var removeElement = function(nums, val) {
let i = 0;
let count = 0;
for (i = 0; i < nums.length - count; i++) {
if (nums[i] === val) {
for (let j = i + 1; j < nums.length; j++) {
nums[j - 1] = nums[j]
}
count++
i--
}
}
return nums.length - count;
}
一种是双指针法,遍历一趟元素,如果当前元素不等于要删除的值,就赋值到i的位置,i再++,如果相等,则跳过,最后会遍历到结束,而i的位置就是不等于删除元素的位置。
var removeElement = function(nums, val) {
let i = 0;
let len = nums.length;
// 找到第一个要删除的数据
for (let j = 0; j < len; j++) {
if (nums[j] !== val) {
nums[i++] = nums[j];
}
}
return i;
};
双指针进化版:上面的元素复制操作较多,不需要赋值的也赋值了,题解中优化解法,一个指向第一个left,一个指向最后一个right。
- 如果元素等于要删除的元素了,则left,right交换,同时,right--
- 如果不相等,则left++
最后i得位置就是最后不想等的元素。
写的时候边界条件容易写错,left <= right,嗯,写了几遍错了。。最后调试出来的。
// 双指针优化解法
var removeElement = function(nums, val) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
if (nums[left] === val) {
let tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
right--;
} else {
left++;
}
}
return left;
}