详细解析:请看Carl老师的讲解

数组基础理论

  • 下标从 0 开始

  • 内存空间地址是连续的

  • 增删元素时,会涉及其他元素地址的变动

704. 二分查找 | 点击查看力扣对应题目

二分法,也叫折半查找法,这里需要注意的是前提条件:

  • 有序数组,采用顺序存储

  • 无重复元素

解题思路

二分法查找基本原理:

首先将要查找的元素(key)与数组的中间元素比较

1、如果key小于中间元素,只需要在数组的前一半元素中继续查找

2、如果key和中间元素相等,匹配成功,查找结束

3、如果key大于中间元素,只需要在数组的后一半元素中继续查找

复杂度:时间复杂度O(logn);循环实现空间复杂度为O(1)

注意:

  • 左右区间一般为“左闭右闭”[left,right] 或者“左闭右开”[left,right)。可以结合数学区间理解。

  • 下标:left:0,right: arr.length-1

  • 区间的定义是不变量,需要分清到底是while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1?

代码1

方法一:左闭右闭【left,right】

注意:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

/*** @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)>>1;if (nums[mid] > target){right = mid - 1;} else if(nums[mid] < target){left = mid + 1 ;}else{return mid;}}return - 1;
};

代码2

方法二:左闭右开【left,right)

注意:

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的

  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

/*** @param {number[]} nums* @param {number} target* @return {number}*/var search = function(nums, target){let left = 0;let right = nums.length;    //定义左闭右开区间while(left < right){let  mid = (left + right)>>1;if (nums[mid] > target){right = mid;} else if(nums[mid] < target){left = mid + 1 ;}else{return mid;}}return - 1;
};

总结

对数据结构比较熟悉,一眼就想到了用折半查找发,难点在于区间定义,之前没有考虑过这个问题,如果把区间界限定义清楚了代码不会很难写。

对于位运算知识点已经忘了,之前还一直在思考为什么使用 (left + right)/2 会报错。

JavaScript 中 的变量 是松散类型 的,可以保存任何类型数据,变量只不过是一个名称。

所以当出现left=0,right=5时,直接使用(left + right) / 2得到的就是2.5 。

那么当值为undefined时,下列的if或者else if中条件都会不符合,这样left和right的值都不会发生变化,由此,就会一直在while中死循环。

27. 移除元素 | 点击查看力扣对应题目

解题思路

双指针:通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组

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

整个过程保持不变的性质是:区间 [0,left) 中的元素都不等于 val。当左右指针遍历完输入数组以后,left 的值就是输出数组的长度。

代码

/*** @param {number[]} nums* @param {number} val* @return {number}*/
var removeElement = function(nums, val) {const n = nums.length;let left = 0;for(let right = 0; right < n; right++){if(nums[right] !== val){nums[left] = nums[right];left++;}}return left;
};

总结

  • 数组在内存空间的地址是连续的,删除其实等于覆盖。

  • 如果每次找到一个元素,都把后面所有元素整体移动一轮,那么时间复杂度是O(n*n)

  • 如果使用快慢指针,只需要遍历一次,就可以把所需要的数字都写到对应的位置,最终返回新数组的长度即可。

这道题最开始想到的方法是使用left和right指针,初始化在数组的两头,同时向中间收缩,right遇到有效数字,就赋值给left,但是发现,同向遍历,是最简单和清晰的写法。

碎碎念

打卡第一天,耗时三个小时多,很多知识点比以前学的更透彻了些。然后因为没带平板来图书馆,所以没有附上手绘图。

【代码随想录算法练习】| DAY01 | JavaScript | 数组理论基础,704. 二分查找,27. 移除元素相关推荐

  1. 代码随想录Day01:数组理论基础、二分查找、移除元素

    目录 数组理论基础.二分查找.移除元素 1.数组理论基础 2.Leetcode704.二分查找 方法一 左闭右闭: 方法二 左闭右开: 方法三 左开右开: 方法四 左开右闭: 3.Leetcode27 ...

  2. Leetcode 704.二分查找 27.移除元素 代码随想录day1

    本系列目的在于跟练代码随想录,以及记录自己在数据结构与算法方面的一些学习 704.二分查找 其实之前自己在随便刷题的时候看过这道题目,就是一个纯新手的大状态,第一次听到二分查找这样的东西,然后跟着题解 ...

  3. 代码随想录算法训练营第一天|704二分查找 27移除元素

    理论基础 1.数组是存放在连续内存空间上的相同类型数据的集合 2.数组可以方便的通过下标索引的方式获取到下标下对应的数据 3.数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要 ...

  4. 代码修炼Day1_LeetCode704二分查找27移除元素

    代码修炼Day1_LeetCode704二分查找&27移除元素 一些数组基本知识 数组下标都是从0开始的 数组内存空间的地址是连续的 题目链接: 力扣704二分查找 二分查找思想 针对升序数组 ...

  5. 代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素

    今日学习的文章链接如下: 代码随想录 (programmercarl.com) 代码随想录 (programmercarl.com) 704. 二分查找 自己看到题目的第一想法 拿到题目首先想办法,一 ...

  6. Day01.二分查找、移除元素

    Day01.二分查找.移除元素 0704.二分查找 题目链接:0704.二分查找 思路:二分查找,仅对有序数组有效.每次需要数组的中间值,与目标值比较大小,如果中间值比目标值大,说明目标值位置在lef ...

  7. 【Day1】数组、704二分查找、27移除元素

    [Day1]数组.704二分查找.27移除元素 数组 704 二分查找 版本一 左闭右闭 即[left, right] 版本二 左闭右开 即[left, right) 27 移除元素 暴力解法 双指针 ...

  8. 代码随想录算法训练营day13 | 239. 滑动窗口最大值 | 347.前 K 个高频元素

    一.239. 滑动窗口最大值 from collections import dequeclass MyQueue: #单调队列(从大到小def __init__(self):self.queue = ...

  9. 代码随想录算法训练营第七天| 哈希表理论基础 ,454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和

    代码随想录算法训练营第七天| 哈希表理论基础 ,454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和 454.四数相加II 建议:本题是 使用map 巧妙解决的问题,好好体 ...

最新文章

  1. SpringBoot之错误处理机制
  2. echarts实现动态传入数据刷新【可执行】
  3. package和import语句_5
  4. 自学python还是报班-零基础python自学还是报培训班?
  5. 电脑下载python教程-python教程pdf下载
  6. 白话Elasticsearch66-针对集群重启时的shard恢复耗时过长问题定制的重要参数
  7. NIFI从mysql导入Hbase
  8. Bzoj 4548: 小奇的糖果(双向链表+排序+树状数组)
  9. 字符数组和字符串的小细节
  10. (四)Raspberry Pi上的人工智能人脸检测
  11. JavaScript函数与对象
  12. DAY8-打卡第八天-2018-1-18
  13. ILSpy .NET反编译工具下载地址
  14. jenkins + docker + SpringBoot
  15. The SPECIALIST Lexicon API
  16. 由二叉树构造赫夫曼树
  17. 火遍全球家喻户晓的小游戏——开心消消乐
  18. Android_Mms源代码接受短信流程
  19. 爬虫实战入门级教学(数据爬取->数据分析->数据存储)
  20. Mars3D平台介绍

热门文章

  1. 微信抢红包的架构设计
  2. 常用的无线网络加密协议
  3. 《MySQL开发规范》过时了,视图的查询性能提升了一万倍
  4. 2023年一起来认识一下StampedLock吧
  5. 使用python基本函数实现简易的《原神》抽卡系统
  6. 支付宝不支持qq邮箱获取账单
  7. 微信小程序04---头像上传、瀑布流、下拉刷新、触底加载更多、分包
  8. [小说连载]张小庆,在路上(12)- 爱情来临
  9. LEADTOOLS 入门教程: 使用 AWS Lambda 转换文档 - C# .NET Core
  10. 企业如何部署开源邮箱系统?