JS代码随想录(一):数组

代码随想录

一、数组理论基础
二、LeetCode 704. 二分查找
三、LeetCode 27. 移除元素
四、LeetCode 977.有序数组的平方
五、LeetCode 209.长度最小的子数组
六、LeetCode 59.螺旋矩阵II
七、数组总结

 一、数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

数组的元素是不能删的,只能覆盖。

二、二分查找 (二分法)

题目:. - 力扣(LeetCode) 

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

错解: (未使用二分法)

var search = function(nums, target) {for(let i = 0; i<nums.length;i++){if(nums[i]==target){return i;}}return -1;
};

正解:

  • 二分法:
  • 这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件 。
  • 对于位移法和防溢出的理解:
  • right - left:计算两个数的差值。
  • (right - left) >> 1:将差值的二进制表示向右移动一位。这相当于将差值除以2,但因为是位操作,所以通常比整数除法更快。
  • left + ((right - left) >> 1):将上述得到的结果加到 left 上,得到中间值 mid
  • 为什么要这样做而不是直接使用 (left + right) / 2 呢?

    当 left 和 right 都是大整数时,left + right 可能会导致整数溢出。例如,在32位整数系统中,如果 left 是 INT_MAX(即最大的32位整数),而 right 是一个大于零的正数,那么 left + right 就会溢出。而使用位操作可以避免这种情况,因为 right - left 的结果一定是小于或等于 right 的,因此向右移动一位(即除以2)后再加上 left 就不会溢出。

左闭右闭: 

  • 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 mid,left=0,right=nums.length-1;//right是数组最后一个数的下标, 要加等号是因为,左闭右闭,当l=r时,也包含在寻找的区间while(left<=right){// // 位运算 + 防止大数溢出mid=left+((right-left)>>1);// 如果mid所在的数大于目标数,就到左边找,所以right要变if(nums[mid]>target){right=mid-1;// 如果mid所在的数小于目标数,就到右边找,所以left改变}else if(nums[mid]<target){left=mid+1;// 如果刚好等于,就返回mid中位数}else{return mid;}}return -1;
};

 左闭右开:

  • 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 mid,left=0,right=nums.length;//right是数组最后一个数的下标+1, 不加等号是因为,nums[right]不在查找范围内while(left<right){// // 位运算 + 防止大数溢出mid=left+((right-left)>>1);// 如果mid所在的数大于目标数,就到左边找,所以right要变if(nums[mid]>target){right=mid;// 如果mid所在的数小于目标数,就到右边找,所以left改变}else if(nums[mid]<target){left=mid+1;// 如果刚好等于,就返回mid中位数}else{return mid;}}return -1;
};

三、 移除元素(快慢指针法)

题目:. - 力扣(LeetCode)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

正确:

  • 数组里面的元素在内存地址中是连续的,是不能删除的,所以要覆盖等于val的值
  • 双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置
/*** @param {number[]} nums* @param {number} val* @return {number}*/
var removeElement = function (nums, val) {// 慢指针let i = 0;// 快指针for (j = 0; j < nums.length; j++) {// 如果快指针不等于val,就把不等于val的值给i,实现覆盖等于val的值if (nums[j] != val) {nums[i] = nums[j];// 覆盖一次,i加1,最后覆盖的次数就是数组的新长度。i++;}}return i;
};

四、有序数组的平方(双指针法)

题目:. - 力扣(LeetCode)

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

 正解:

  • 双指针法:

我们可以从数组的两端向中间遍历,同时比较两端的元素平方后的大小,并将较大的那个平方值添加到结果数组的开头(因为我们是从后向前添加到结果数组的,以保持顺序)。

  • 在JavaScript中,Array.prototype.unshift() 是一个数组方法,用于在数组的开头添加一个或多个元素,并返回新的数组长度。但是,它实际上会修改原始数组,并在其开头添加元素。

在您给出的代码示例中:

  • result.unshift(leftSquare); 会在 result 数组的开头添加 leftSquare 的值。
  • result.unshift(rightSquare); 会在 result 数组的开头添加 rightSquare 的值。
/*** @param {number[]} nums* @return {number[]}*/
var sortedSquares = function(nums) {const result = [];// 新数组存放// left指向开头的指针,right指向数组末尾的指针let left = 0, right=nums.length-1;// 从两端开始同时计算平方并比较while(left<=right){const lefts = Math.pow(nums[left], 2);const rights = Math.pow(nums[right], 2);// 将较大的平方值添加到结果数组的开头// 如果lefts大于rights,就把lefts放到新数组最前面if(lefts>rights){result.unshift(lefts);left++}else{// 反之,就把rights放到新数组最前面result.unshift(rights);right--;}}return result;
};

五、长度最小的子数组 (滑动窗口)

. - 力扣(LeetCode)

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 连续

子数组

 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

正解:

滑动窗口(双指针) :

滑动窗口

所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果

var minSubArrayLen = function(target, nums) {// 滑动算法let left = 0;  let sum = 0;  // 最小长度为无穷大let minLength = Infinity;  for (let right = 0; right < nums.length; right++) {  sum += nums[right];  // 当窗口内的和大于等于目标值时,移动左指针缩小窗口  while (sum >= target) {  minLength = Math.min(minLength, right - left + 1);  sum -= nums[left];  left++;  }  }  
//  如果找到了,就返回最小子数组的长度;如果没有找到,就返回 0。
// minLength 等于 Infinity就返回0,不等于就返回minLengthreturn minLength === Infinity ? 0 : minLength;   
};

六、螺旋矩阵

. - 力扣(LeetCode)

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

正解: 

  1. 初始化矩阵
    首先,需要创建一个大小为 n x n 的矩阵(二维数组),并将所有元素初始化为0或者其他占位符。这个矩阵将用于存放最终的结果。

  2. 设置边界和填充数字
    确定矩阵的四个边界:上边、下边、左边和右边。开始时,上边是矩阵的第一行,下边是最后一行,左边是第一列,右边是最后一列。同时,设置一个变量来跟踪当前要填充的数字,初始值为1。

  3. 按顺时针螺旋填充
    按照“上边 → 右边 → 下边 → 左边”的顺序,依次填充数字。每次填充完一个边后,调整相应的边界,并继续填充下一个边,直到所有格子都被填满。

    • 填充上边:从左到右,填充上边的每个格子,并将上边界下移一行。
    • 填充右边:从上到下,填充右边的每个格子,并将右边界左移一列。
    • 填充下边:在确保下边还有未填充的格子后,从右到左填充下边的每个格子,并将下边界上移一行。
    • 填充左边:在确保左边还有未填充的格子后,从下到上填充左边的每个格子,并将左边界右移一列。
  4. 重复填充过程
    重复步骤3,直到所有的格子都被填满,即当前填充的数字达到 n^2 + 1(因为我们是从1开始填充的,所以当数字大于 n^2 时,说明所有格子已经填满)。

  5. 返回结果
    当所有格子都填满后,返回填充好的矩阵。

这种解题思路的关键在于如何正确地更新边界,并在填充过程中保持顺时针螺旋的顺序。通过不断地缩小边界范围,并依次填充每个边界上的格子,最终可以得到所需的矩阵。

/*** @param {number} n* @return {number[][]}*/
var generateMatrix = function(n) {// 初始化一个 n x n 的二维数组(矩阵),并用 0 填充所有元素  let matrix = Array(n).fill(0).map(() => Array(n).fill(0));  // 初始化要填充的数字为 1  let num = 1;  // 定义矩阵的四个边界:上、下、左、右  let rowStart = 0, rowEnd = n - 1, colStart = 0, colEnd = n - 1;  // 当要填充的数字小于等于 n^2 时,继续填充  while (num <= n * n) {  // 从左到右填充上边界(横向)  for (let j = colStart; j <= colEnd; j++) {  matrix[rowStart][j] = num++;  }  // 上边界填充完毕后,上边界下移一行  rowStart++;  // 从上到下填充右边界(纵向)  for (let i = rowStart; i <= rowEnd; i++) {  matrix[i][colEnd] = num++;  }  // 右边界填充完毕后,右边界左移一列  colEnd--;  // 从右到左填充下边界(如果还存在未填充的元素)  for (let j = colEnd; j >= colStart; j--) {  matrix[rowEnd][j] = num++;  }  // 下边界填充完毕后,下边界上移一行  rowEnd--;  // 从下到上填充左边界(如果还存在未填充的元素)  for (let i = rowEnd; i >= rowStart; i--) {  matrix[i][colStart] = num++;  }  // 左边界填充完毕后,左边界右移一列  colStart++;  }  // 返回填充好的矩阵  return matrix; 
};

七、总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/10447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

boost asio同步编程(附源码api)

首先注明&#xff0c;这里我写的都是关于tcp的通信。 通信大致流程 创建端点 创建tcp端点的api是boost::asio::ip::tcp::endpoint; 当然创建udp端点的api则是boost::asio::ip::udp::endpoint; 是一个表示 TCP/UDP 端点的类&#xff0c;在 Boost.Asio 库中用于网络编程。它通…

鸿蒙ArkUI:【编程范式:命令式->声明式】

命令式 简单讲就是需要开发用代码一步一步进行布局&#xff0c;这个过程需要开发全程参与。 开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 Objective-C ObjectiveC 复制代码 UIView *cardView …

day3_prefixSum

一、前缀和技巧 重点 前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和 个人理解&#xff1b;预计算&#xff0c;空间换时间 1.(一维数组的前缀和)303区域和检索-数组不可变 获取闭区间值 [left,right] -> preSum[right 1] - preSum[left],其中preSum[right…

Linux下VMamba 环境复现+环境测试

# 1. 创建自己的虚拟环境 conda create -n VMamba python3.10.13 conda activate VMamba # 2. cuda-11.8 conda install cudatoolkit11.8 -c nvidia # 3. torch torchvision torchaudio 与 官网命令一致 pip install torch2.1.1 torchvision0.16.1 torchaudio2.1.1 --index-url…

苹果电脑怎么清内存?2024有哪些好用的工具?

在使用苹果电脑的过程中&#xff0c;我们可能会遇到系统运行缓慢、程序响应迟缓或频繁出现应用程序崩溃的情况&#xff0c;这些问题很可能是由于内存占用过高所导致。内存&#xff0c;或称为RAM&#xff08;RandomAccessMemory&#xff09;&#xff0c;是计算机的临时存储区&am…

超级好看的html网站维护源码

源码介绍 好看的html网站维护源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c; 源码截图 源码下载 好看的html网站维护源码

py黑帽子学习笔记_网络编程工具

tcp客户端 socket.AF_INET表示使用标准IPV4地址和主机名 SOCK_STREAM表示这是一个TCP客户端 udp客户端 udp无需连接&#xff0c;因此不需要client.connect这种代码 socket.SOCK_DGRAM是udp的 tcp服务端 server.listen(5)表示设置最大连接数为5 发现kill server后端口仍占用…

【服务治理中间件】consul介绍和基本原理

目录 一、CAP定理 二、服务注册中心产品比较 三、Consul概述 3.1 什么是Consul 3.2 Consul架构 3.3 Consul的使用场景 3.4 Consul健康检查 四、部署consul集群 4.1 服务器部署规划 4.2 下载解压 4.3 启动consul 五、服务注册到consul 一、CAP定理 CAP定理&#xff…

i春秋-Backdoor

题目 考点 git源码泄露 Linux文件恢复 代码审计 http 解题 参考wp https://blog.csdn.net/cbhjerry/article/details/105791056https://www.pianshen.com/article/19461342501/扫描 题目给出提示&#xff1a;敏感文件泄漏 于是使用dirsearch扫一下 python dirsearch.py -…

ICode国际青少年编程竞赛- Python-4级训练场-while语句综合

ICode国际青少年编程竞赛- Python-4级训练场-while语句综合 1、 for i in range(4):while not Flyer[i].disappear():wait()Spaceship.step(6)Spaceship.turnLeft()2、 Dev.turnLeft() for i in range(4):Spaceship.step(2)while Flyer[i].disappear():wait()Dev.step(4)Dev.…

Failed to parse source map (@toast-ui/editor/dist/purify.js.map)

使用 toast-ui-editor 时出现报错&#xff1a;Failed to parse source map (toast-ui/editor/dist/purify.js.map) 解决方法很简单&#xff1a; "start": "set "GENERATE_SOURCEMAPfalse" && react-scripts start ",在启动脚本时添加执…

程序员代码面试指南题目解析(一)

题目一&#xff1a;如何仅用递归函数和栈操作逆序一个栈 题目要求&#xff1a; 一个栈依次压入 1、2、3、4、5&#xff0c;那么从栈顶到栈底分别为5、4、3、2、1。将这个栈 转置后&#xff0c;从栈顶到栈底为 1、2、3、4、5&#xff0c;也就是实现栈中元素的逆序&#xff0c;但…

【吴恩达机器学习-week2】多个变量的线性回归问题

文章目录 1.1 目标2 问题陈述2.1 包含我们示例的矩阵 X2.2 参数向量 w \mathbf{w} w 和 b b b 3 使用多个变量进行模型预测3.1 逐元素单独预测3.2 单一预测&#xff0c;向量 4 使用多个变量计算成本5 使用多个变量的梯度下降5.1 使用多个变量计算梯度 多个变量的梯度下降小结…

搜歌网搜索各种类型音乐,统统歌曲转换格式mp3,轻松实现音乐自由!

在互联网的广阔天地中&#xff0c;音乐爱好者们总能找到满足自己需求的平台。其中&#xff0c;支持全网搜歌的网站无疑是一个值得推荐的音乐探索乐园。无论是寻找经典老歌&#xff0c;还是发掘新兴音乐&#xff0c;搜他们都能为音乐爱好者提供一站式的服务。 一般支持全网搜索…

值得收藏!!《软考信息处理技术员》必背100母题,轻松45+

距离软考考试的时间越来越近了&#xff0c;趁着这两周赶紧准备起来 今天给大家整理了——软考信息处理技术员100道经典母题&#xff0c;年年从里面抽&#xff0c;有PDF&#xff0c;可打印&#xff0c;每天刷几道。 第一章 电脑的基本操作 1、&#xff08; &#xff09;不是国产…

Linux线程(二)线程互斥

目录 一、为什么需要线程互斥 二、线程互斥的必要性 三、票务问题举例&#xff08;多个线程并发的操作共享变量引发问题&#xff09; 四、互斥锁的用法 1.互斥锁的原理 2、互斥锁的使用 1、初始化互斥锁 2、加锁和解锁 3、销毁互斥锁&#xff08;动态分配时需要&#…

RFID在汽车制造中的应用如何改变行业

随着工业4.0和中国制造2025的推进&#xff0c;企业对于智能化、自动化的需求日益增长&#xff0c;RFID射频技术在制造业中已经相当普遍了。在如今这瞬息万变的行业与时代中&#xff0c;RFID技术可以帮助企业获得竞争优势&#xff0c;简化日益复杂的生产流程&#xff0c;推动企业…

C语言实战项目---通讯录

项目要实现的内容&#xff1a;能够存放100个人的通讯录程序&#xff0c;能够实现联系人数据的存储&#xff0c;删除&#xff0c;修改&#xff0c;查找&#xff0c;展示联系人的信息。 所需知识&#xff1a;结构体&#xff0c;指针&#xff0c;函数................. 废话不多…

2016-2021年全国范围的2.5m分辨率的建筑屋顶数据

一、论文介绍 摘要&#xff1a;大规模且多年的建筑屋顶面积&#xff08;BRA&#xff09;地图对于解决政策决策和可持续发展至关重要。此外&#xff0c;作为人类活动的细粒度指标&#xff0c;BRA可以为城市规划和能源模型提供帮助&#xff0c;为人类福祉带来好处。然而&#xf…

Qt之常用控件一

Widget常见属性及其作用 属性作用enabled 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤ geometry 位置和尺⼨. 包含 x, y, width, height 四个部分. 其中坐标是以⽗元素为参考进⾏设置的. windowTitle 设置 widget 标题 windowIcon 设置 widget 图标 windowOpa…