前言
作为工作了近五年的低端码农,深知自己的计算机基础极其拉垮,算法什么的一概不知,曾经自己也刷过了leetcode,但是由于自己没有计划和工作的的原因,都是没刷几天就荒废了。希望这次跟着卡哥和小伙伴儿们,可以坚持把这60天的题都刷完,加油!
704.二分法查找
真的是基础不好,审题之后思考了好一会也没有好的思路,看了一会解题的思路才有点明白了。
左闭右开
var search = function(nums, target) {
let left = 0;
let right = nums.length;//因为是左闭右开,left不会等于right,right初始化值的时候不需要数组长度减1
while(left<right){
const mid = Math.floor((right-left)/2)+left; // 防止内存溢出,js固定写法,记住即可
if(nums[mid]>target){
right = mid
}else if(nums[mid]<target){
left = mid + 1
}else{
return mid
}
return -1
}
}
左闭右闭
var search = function(nums, target) {
let left = 0;
let right = nums.length - 1;//因为是左闭右闭,left会等于right,right初始化值的时候需要数组长度减1
while(left<=right){
const mid = Math.floor((right-left)/2)+left; // 防止内存溢出,js固定写法,记住即可
if(nums[mid]>target){
right = mid -1
}else if(nums[mid]<target){
left = mid + 1
}else{
return mid
}
return -1
}
}
27. 移除元素
暴力双循环
双指针的写法理解之后,是要比暴力破解双循环的要更容易让人理解的,暴力双循环对我来说,数组移位往往考虑不到,返回新的数组长度比较简单,但是返回的新的数组有些难度。
var removeElement = function(nums, val) {
let length=nums.length;
for(let i=0;i<nums.length;i++){
if(nums[i]===val){
for(let j=i+1;j<nums.length;j++){
nums[i]=nums[j]
}
}
i--
length--
}
return length
}
拷贝覆盖
参考的leetcode精选题解
主要思路是遍历数组 nums,同时设置一个新数组的初始长度length为0,在遍历过程中如果出现元素与需要移除的值不相同时,则进行拷贝覆盖 nums[length] = num[i],length 自增 1。
如果相同的时候,则跳过该数字不进行拷贝覆盖,最后 length 即为新的数组长度
这种思路在移除元素较多时更适合使用,最极端的情况是全部元素都需要移除,遍历一遍结束即可
var removeElement = function(nums, val) {
let length=0;
for(let i=0;i<nums.length;i++){
if(nums[i]!==val){
nums[length]=nums[i]
length++
}
}
return length
}
快慢双指针
当慢指针的元素不等于val的时候,快慢指针一起向右走,慢指针++,当满指针的元素等于val的时候,慢指针暂停,快指针继续走,直到快指针遍历结束
var removeElement = function(nums, val) {
let slow=0;
for(let fast=0;fast<nums.length;fast++){
if(nums[slow]!==val){
mums[slow]=nums[fast]
slow++
}
}
return slow
}
左右双指针
当左指针的元素等于val时,可以吧右指针的元素直接覆盖到左指针的位置,然后,右指针减一向左走,左指针暂停。当当左指针的元素不等于val时,左指针加一向右走。直到左指针不小于右指针结束
var removeElement = function(nums, val) {
let left=0; left right = nums.length;
while(left<right){
if(nums[left]===val){
nums[left]=nums[right-1]
right --
}else{
left ++
}
}
return left
}