代码随想录算法训练营第一天|LeetCode704 二分查找 27移除元素(3.2补做)

题目链接

力扣

今日学习的文章链接

代码随想录

想法

看完之后

基本题意

 n个元素 升序 int数组 目标值 target 

看数组中 有没有target 存在 返回下标 否则-1

var search = function(nums, target) {

// 基本语法都不会了。。

// 暴力法 一个for循环 

// 二分法 mid left right

// if mid<target 右边区间  否则左区间

// 重复 缩小区间

// 等于时找到  取下标值 

// 找不大 就 return -1

// 数组左右端点的下标

但不知道怎么实现

看完代码随想录之后的想法

了解数组左闭右闭的写法 

区间的定义决定二分法代码该如何写

左闭右闭的区间

while里的条件要写成<= 因为left=right 有意义

二分查找左闭右开

右开是因为 在求right时不减一,实际上数组长度为right时,最大的下标为right-1

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */

//  n个元素 升序 int数组 目标值 target 
// 看数组中 有没有target 存在 返回下标 否则-1
var search = function(nums, target) {
// 基本语法都不会了。。
// 暴力法 一个for循环 
// 二分法 mid left right
// if mid<target 右边区间  否则左区间
// 重复 缩小区间
// 等于时找到  取下标值 
// 找不大 就 return -1
// 数组左右端点的下标
// let left =0
// let right = nums.length-1
// // 用左闭右闭的写法
// while(left<=right){
//     // let mid = (left+right)/2 不能用这个 5/2 为2.5 不会取整
//     mid = left + ((right - left) >> 1);//位运算 求2分之1
//     if(nums[mid]>target){
//         right=mid-1
//     }else if(nums[mid]<target){
//         left=mid+1
//     }else{
//         return mid
//     }
// }
// return -1

// 用左闭右开的 那个开其实就相当于闭的时候长度+1 但是是开区间
let left = 0
let right = nums.length //闭的话就是-1 

// 二分法用的是中间值和它比
while(left<right){
    let middle = Math.floor((left+right)/2)
    if(nums[middle]>target){
        right=middle //开区间[left,middle)
    }
    else if(nums[middle]<target){
        left=middle+1
    }
    else{
        return middle
    }
}
return -1
};

自己实现过程中遇到哪些困难

第一次使用LeetCode,不知到该怎么使用。。。

它会默认定义一些题目中的变量

这题的话

像数组它已经定义好了 还有目标值target

还有使用JS时 忘记数组怎么定义的了

var arr = []

在求mid时

// let mid = (left+right)/2 不能用这个 5/2 为2.5 不会取整

用位运算

mid = left + ((right - left) >> 1);//位运算 求2分之1

题目链接(移除元素)

力扣

今日学习的文章链接

代码随想录

想法

看完之后

基本题意

// 数组 nums 值val 

// 移除值为val的元素 返回数组长度

不太理解题目意思。。 没有思路

看完代码随想录之后的想法

// 思路 在内存空间中是连续存储的 数组中的元素不能单独删除,只能覆盖

// 暴力法

// 两层for循环 一层循环遍历数组 一层更新数组

在第一层for循环

判断与val是否相等

相等

写第二层for循环(j=i) 更新数组

因为数组中的元素在内存空间中是连续存储的不能单独删除,只能覆盖

nums[j]=nums[j]+1 //数组元素往前移动一位

第二层循环遍历后就更新完数组了

因为遍历完后i会++。但元素已经向前移动一位了,对应的下标也得向前移动一位,不然占据val位置的元素会跳过判断,所以i--

双指针法(看题解能理解)

快指针:寻找新数组的元素

慢指针:指向更新 新数组下标的位置

当val == nums[fastIndex] 时 slowIndex不会增加 所以就能求出新数组的长度

但fastIndex会++

到下一轮循环时,!=   时  下标为fastIndex的元素就往前移了一位

var removeElement = function(nums, val) {
    // 双指针 快慢指针
    // 快指针:寻找新数组的元素
    // 慢指针:指向更新 新数组下标的位置
    let fastIndex=0
    let slowIndex=0
    for(fastIndex=0;fastIndex<nums.length;fastIndex++){
        if(val!=nums[fastIndex]){
            nums[slowIndex]=nums[fastIndex]
            slowIndex++
        }
    }
    return slowIndex

};

自己实现过程中遇到哪些困难


var removeElement = function(nums, val) {

// 暴力法
// 两层for循环 一层循环遍历数组 一层更新数组
let i =0
let j =0
let size = nums.length
for(i= 0;i<size;i++){
if(nums[i]==val){
    for(j=i;j<size;j++){
        nums[j]=nums[j+1]//后一个元素覆盖前一个元素
    }
    i--//这个不太理解 因为更新完数组后 i++ 而我们更新数组时 后面的元素已经往前移了一位,如果不减减的话,占据原本val位置的元素不会被判断
    size--//数组长度-1
}
}
return size


};

今日收获

虽然今天花了比较多时间只做了一道题,但是还是有不少的收获,对数组理论基础和二分查找有了一定的理解

后面补做了移除元素,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值