蓝桥:前端开发笔面必刷题——Day2 数组(二)

news2025/1/9 19:57:11

文章目录

  • 📋前言
  • 🎯删除有序数组中的重复项
    • 📚题目内容
    • ✅解答
  • 🎯移动零
    • 📚题目内容
    • ✅解答
  • 🎯长度最小的子数组
    • 📚题目内容
    • ✅解答
  • 🎯反转字符串数组
    • 📚题目内容
    • ✅解答
  • 📝最后


在这里插入图片描述

📋前言

这个系列的文章收纳的内容是来自于蓝桥云课的前端岗位笔面必刷题的内容,简介是:30天133题,本题单题目全部来自于近2年BAT等大厂前端笔面真题!因为部分题目是需要会员,所以该系列的文章内容并非完全全面(如果需要会员的题目,则从 leetcode 补充对应的题目,题目大概也是一样的考法)。文章中题目涉及的内容包括原题、答案和解析等等。
在这里插入图片描述


🎯删除有序数组中的重复项

📚题目内容

给你一个升序排列的数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持 一致 。

不要使用额外的空间,你必须在原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。

输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4

题目给的测试用例里有以下限制:

  • 1 <= nums.length <= 22
  • 0 <= nums[i] <= 7
  • nums 已按升序排列。

✅解答

初始提供代码

function removeDuplicates(nums) {
  // 补充代码
}

答案

function removeDuplicates(nums) {
  return [...new Set(nums)].length
}

删除数组中重复的数据,顾名思义可以理解为数组去重,这样就有很多种方法去解决这个问题,一行代码即可。使用 Set 数据结构的特性去掉数组中重复的元素,并将去重后的元素重新存储到一个新的数组中。最终返回这个新数组的长度,也就是去重后数组的元素个数。


🎯移动零

📚题目内容

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

输入: nums = [0, 1, 0, 3, 12];
输出: [1, 3, 12, 0, 0];
输入: nums = [0];
输出: [0];

题目给的测试用例里有以下限制:

  • 1 <= nums.length <= 5
  • 0 <= nums[i] <= 12

✅解答

初始提供代码

function moveZeroes(nums) {
  // 补充代码
}

这题很有意思,同样的解法也有很多种,题目中的一句话其实很关键“必须在不复制数组的情况下原地对数组进行操作”。因此这题写看看多种答案的解法和情况。
答案1️⃣
我做的时候没想太多其他情况,所以就一股脑的解了,先遍历数组找到为 0 的项,然后先用 splice 方法删除 0 ,再用 push 方法添加 0,代码如下。

function moveZeroes(nums) {
  for(let i=0;i<nums.length;i++){
    if(nums[i]===0)
    {
        nums.splice(i,1)
        nums.push(0)
    }
  }
    return nums
}

如果直接使用 for 循环遍历数组并且在循环体内使用 splice 方法来删除元素,会导致数组长度发生变化,从而导致某些元素被遗漏或重复处理。为了避免这个问题,我们可以倒着遍历数组,并在循环体内使用 splice 方法来删除元素,这样就不会影响到前面的元素。代码如下。

function moveZeroes(nums) {
  for(let i=0;i<nums.length-1;i++){
    if(nums[i]===0)
    {
        nums.splice(i,1)
        nums.push(0)
    }
  }
    return nums
}

然这个算法也可以实现将所有 0 元素移动到数组末尾,但是它的时间复杂度是 O(n^2),因为每次删除元素都要移动后面的元素,所以在遇到大规模的数组时会比较慢。

答案2️⃣

function moveZeroes(nums) {
    let i = 0, j = 0;
    while (i < nums.length) {
        if (nums[i] !== 0) {
            nums[j++] = nums[i];
        }
        i++;
    }
    while (j < nums.length) {
        nums[j++] = 0;
    }
	return nums;
}

该函数的实现中,定义两个指针 i 和 j,初始时都指向数组的第一个元素。然后遍历数组,如果当前元素 nums[i] 不为 0,则将其赋值给 nums[j],同时将指针 j 右移;否则将指针 i 右移,跳过这个 0 元素。最后,将 j 指针之后的所有元素都赋值为 0 即可。

这个算法只需要遍历数组一次,时间复杂度是 O(n),并且不需要额外的空间,是一种比较高效的原地操作方法。

答案3️⃣
这个答案是看到其他同学发的题解,我的评价是很炸裂,先不论性能以及可读性,这个答案在这题的题解中也是很亮眼,只用了一行代码解决了这题。代码如下。

function moveZeroes(nums) {
    return nums.sort((a, b) => !a - !b)
}

这个算法的思路是先将数组中的所有元素转换为布尔值,然后根据布尔值的大小关系进行排序,最后返回排序后的结果。

由于 JavaScript 中 0 是 false,非 0 是 true,所以将一个数转换成布尔值其实就是判断它是否为 0 。因此,这个算法的核心就是利用 sort() 方法的排序函数来比较两个元素的布尔值大小。

具体来说,排序函数接受两个参数 a 和 b,如果 !a - !b 的结果为正数,则表示 a 的布尔值为 false,b 的布尔值为 true,此时应该交换 a 和 b 的位置,使得 a 排在 b 前面;否则就不需要交换位置。最终排序的结果就是将所有非零元素排在了前面,所有零元素排在了后面。

这个算法虽然也只需要遍历数组一次,但是由于使用了 sort() 方法,时间复杂度取决于具体的排序算法,最坏情况下可能会达到 O(n^2),并且这个算法改变了原数组的顺序,不是一个原地操作方法。我是没想到还可以这样的解法的,只能说大佬牛逼(我只是算法萌新),但是我觉得还是 答案2️⃣ 效果较优,但是算法题能通过检测就完了,不是实际开发的逻辑处理,飘一下也不是不行。


🎯长度最小的子数组

📚题目内容

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

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
输入:target = 4, nums = [1,4,4]
输出:1
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

题目给的测试用例里有以下限制:

  • 1 <= target <= 11
  • 1 <= nums.length <= 8
  • 1 <= nums[i] <= 4

✅解答

初始提供代码

function minSubArrayLen(target, nums) {
  // 补充代码
}

答案

function minSubArrayLen(target, nums) {
    let left = 0;
    let sum = 0;
    let res = Infinity;
    for (let right = 0; right < nums.length; right++) {
        sum += nums[right];
        while (sum >= target) {
            res = Math.min(res, right - left + 1);
            sum -= nums[left];
            left++;
        }
    }
    return res === Infinity ? 0 : res;
}

这道题小难啊,可以用双指针来解,两个指针 leftright 分别表示当前子数组的左右端点位置,初始值都为 0。然后用 sum 表示当前子数组的和,初始值为 0 。

  • 每一轮循环,将 right 向右移动一位,即 right = right + 1,同时将 sum 加上 nums[right]
  • 如果 sum >= target,则更新结果 res = Math.min(res, right - left + 1),并将 left 向右移动一位,即 left = left + 1,同时将 sum 减去 nums[left - 1],使得 sum 变为不包括 nums[left - 1] 的子数组的和(如果 sum >= target,那么减去 nums[left - 1] 并不会影响结果)。
  • 如果 sum < target,继续执行第 1 步。直到 right 超出了数组范围,算法结束。

需要注意的是,在实现时需要初始化 resINT_MAX,而不是 0。这是因为当数组中所有元素之和都小于 target 的时候,算法应该返回 0,而不是第一个元素的下标 0。

该函数的时间复杂度是 O(n),其中 n 是数组的长度。


🎯反转字符串数组

📚题目内容

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

题目给的测试用例里有以下限制:

  • 1 <= s.length <= 6
  • s[i] 都是 ASCII 码表中的可打印字符。

✅解答

初始提供代码

function reverseString(s) {
  // 补充代码
}

答案
看到题目第一眼,是不是偷笑了?反转字符串数组,我一个 reverse 方法搞定它,没毛病吧!?如果这题真是这样那其实没啥意思,注意看这句话 “不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。” 所以我们要思考其他解决方法,符合题目要求的方法。代码如下。(虽然直接用 reverse 方法 通过了测试hhh)
在这里插入图片描述

function reverseString(s) {
    let left = 0;
    let right = s.length - 1;
    while (left < right) {
        const tmp = s[left];
        s[left] = s[right];
        s[right] = tmp;
        left++;
        right--;
    }
    return s
}

这题也是用双指针的方法来解决的,将指针分别指向字符串的头尾,然后不断交换两个指针所指向的字符。

  • 初始化左指针 left 为 0,右指针 right 为字符串长度减一。
  • left < right 时,交换 s[left] 和 s[right],然后将 left 加 1,将 right 减 1。
  • left >= right 时,反转结束。

该函数接受一个字符数组 s 作为参数,直接修改了原数组,符合了题目的要求。


📝最后

感谢阅读到这,这就是Day2 的全部内容了,文章内容中题目的答案都是通过检测的了,如果有疑问和争议的内容,可以评论区留言和私信我,收到消息第一时间解答和回复。(来自詹姆斯的点赞👍)
在这里插入图片描述

🎯点赞收藏,防止迷路🔥
✅感谢观看,下期再会📝
@CSDN | 黛琳ghz

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

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

相关文章

麒麟操作系统软件更新灾难连篇之二:QQ罢工

在解决了中文输入法消失的问题后&#xff0c;还没缓过气来&#xff0c;又发现QQ罢工了&#xff1a;双击电脑桌面上的QQ图标&#xff0c;没有显示QQ登录界面。 重启电脑再试&#xff0c;还是不显示QQ登录界面。 前不久腾讯正式宣布&#xff0c;QQ Linux 版 3.0 已在 QQ 官网上…

最好用的文本与文件查询软件AnyTXT Searcher与Listary简介

1. 工具简介 1.1 Listary简介 Listary是一个革命性的Windows搜索工具&#xff0c;借助 Listary软件&#xff0c;你可以快速搜索电脑文件、定位文件、执行智能命令、记录访问历史、快速切换目录、收藏常用项目等。 Listary为Windows传统低效的文件打开/保存对话框提供了便捷、…

Apache Tomcat AJP协议文件读取与包含

永远也不要忘记能够笑的坚强&#xff0c;就算受伤&#xff0c;我也从不彷徨。 0x01.漏洞情况分析 Tomcat是Apache软件基金会Jakarta 项目中的一个核心项目&#xff0c;作为目前比较流行的Web应用服务器&#xff0c;深受Java爱好者的喜爱&#xff0c;并得到了部分软件开发商的…

makefile 学习(2):C语言的编译及库文件的生成与链接

文章目录 1. 介绍2. C语言编译2.1 预处理2.2 生成汇编语言2.3 编译目标文件2.4 编译为可执行文件 3. .a静态库的编译与链接案例 4 .so 动态库的编译与链接 1. 介绍 编译C语言的相关后缀 .a 文件是一个静态库文件.c文件是c语言的源文件.h c语言的头文件.i 是预处理文件.o 目标文…

两个用字符串表示的大数字的和

文章目录 题目详情Java实现分析Java 怎么获取到字符串中的对应位置的数字值Java完整代码测试验证 python实现python 怎么获取到字符串中的对应位置的数字值python完整代码 总结 这是遇到的一道快手数仓岗位的面试题目&#xff0c;题目大意如下&#xff1a; 题目详情 现在有两个…

【树莓派4B安装18.04桌面+远程SSH】

【树莓派4B安装18.04桌面远程SSH】 1. 前言2 .树莓派安装ubuntu18.04 系统2.1 下载ubuntu Server 18.04 的镜像包2.2 镜像烧录2.3 高级设置2.4 配置WiFi2.5 ssh文件配置2.6 Pi 4B启动文件 3. 安装finalshell3.1 windows版下载3.2 windows版安装3.3 SSH连接 4. 安装ubuntu桌面4.…

【野火启明_瑞萨RA6M5】梦的开始 ---- 点灯(寄存器)

文章目录 一、IOPORT简介二、IOPORT的框图分析三、IOPORT的寄存器描述1. 端口引脚功能选择寄存器2. 端口输出数据寄存器3. 端口输入数据寄存器4. 端口输出置位/复位寄存器5. 写保护寄存器 四、点亮LED灯&#xff08;寄存器&#xff09; 从本文开始&#xff0c;我将以瑞萨RA系列…

【夜莺(Flashcat)V6监控】3.链路追踪

链路追踪 介绍 链路追踪是分布式系统下的一个概念&#xff0c;它的目的就是要解决上面所提出的问题&#xff0c;也就是将一次分布式请求还原成调用链路&#xff0c;将一次分布式请求的调用情况集中展示&#xff0c;比如&#xff0c;各个服务节点上的耗时、请求具体到达哪台机…

Java 把一个 List 转换为字符串

在本快速指南中&#xff0c;我们将会解释如何在 Java 把一个 List 转换为 String 字符串。 这个在某些特定的场合可能比较有用&#xff0c;比如说在控制台中输出 List 中的内容&#xff0c;转换为可以人为阅读的内容来进行调试。 使用 List 中标准的 toString() 方法 一个最简…

(2)数码管

LED数码管:数码管是一种简单、廉价的显示器&#xff0c;是由多个发光二极管封装在一起组成"8"字器件 51单片机是共阴极连接 74HC245这个芯片有什么作用呢&#xff1f;解&#xff1a;这个芯片被称之为双向数据缓冲器这个芯片的作用&#xff0c;用来进行数据缓冲(提高驱…

【网络编程】详解UDP/TCP套接字的创建流程

目录 一、网络编程套接字 1、一些概念 1.1源IP地址和目的IP地址 1.2端口号port 1.3TCP和UDP的性质 1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数 2、UDP套接字 2.1UDP服务器创建流程 2.2UDP客户端创建流程 2.3创建socket套接字 2.4绑定套接字对应…

快速找出PATH 路径下重复的命令程序文件

RT&#xff0c;就是想找出命名冲突的可执行文件。日积月累的&#xff0c;PATH 环境变量里乱七八糟堆了一堆东西&#xff0c;很可能想叫一个命令出来&#xff0c;结果实际执行的是另一个地方的程序。 Python 脚本 import ospath os.environ[PATH] folders path.split(;) fil…

理解HttpSession

什么是session 在我刚刚从事后端开发的时候&#xff0c;有一个问题困扰了我很久。 就有个玩意叫session。 PostMapping("login")public Result login(RequestParam("id") String id,RequestParam("password") String password, HttpSession se…

哈希及模拟实现

文章目录 哈希1. 哈希相关概念1.1 哈希概念1.2 哈希冲突1.3 哈希函数1.4 哈希冲突解决1.4.1 闭散列/开放定址法(1)线性探测(2) 二次探测 1.4.2 开散列/哈希桶 2. 开放定址法的实现2.1 结构2.2 插入Insert2.2.1 传统写法2.2.2 现代写法 2.3 查找Find2.4 删除Erase2.5 整体代码 3…

springcloud基于web的智慧养老平台

系统分析 可行性分析 在开发系统之前要进行系统可行性分析&#xff0c;目的是在用最简单的方法去解决最大的问题&#xff0c;程序一旦开发出来满足了用户的需要&#xff0c;所带来的利益也很多。下面我们将从技术、操作、经济等方面来选择这个系统最终是否开发。 1、技术可行…

一图看懂 dateutil 模块:Python datetime 模块的扩展,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 dateutil 模块&#xff1a;Python datetime 模块的扩展&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&#x1f9ca;模块图&#x1f9ca;类关系…

005、数据库结构

数据库结构 1、数据库集簇逻辑结构2、对象标识符3、数据库集簇物理结构4、其它目录结构表空间物理文件位置1、数据库集簇逻辑结构 • 数据库集簇逻辑结构 数据库 : 把数据逻辑分开存放。 对象是放在数据库当中。表空间: 把数据从逻辑或者物理上分割存放2、对象标识符 Postg…

Weblogic SSRF 漏洞(CVE-2014-4210)

SSRF漏洞 ​ SSRF&#xff08;服务端请求伪造&#xff09;&#xff0c;指的是攻击者在未能取得服务器所有权限时&#xff0c;利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。 ​ 简单的说就是利用一个可…

《统计学习方法》——隐马尔可夫模型(下)

学习算法 HMM的学习&#xff0c;在有观测序列的情况下&#xff0c;根据训练数据是否包含状态序列&#xff0c;可以分别由监督学习算法和无监督学习算法实现。 监督学习算法 监督学习算法就比较简单&#xff0c;基于已有的数据利用极大似然估计法来估计隐马尔可夫模型的参数。…

详解二叉树

&#x1f308;目录 一、树形结构​ &#x1f333;1.1 概念1.2 其他概念1.3 树的表示形式 二、二叉树✨2.1 概念2.2 两种特殊二叉树2.3 性质2.4 二叉树存储 三、二叉树的基本操作&#x1f64c;3.1 前置说明3.2 二叉树的遍历3.3 二叉树的基本操作 四、二叉树的OJ✍️ 一、树形结构…