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

news2024/12/23 18:04:10

文章目录

  • 📋前言
  • 🎯两数之和 II
    • 📚题目内容
    • ✅解答
  • 🎯移除元素
    • 📚题目内容
    • ✅解答
  • 🎯有序数组的平方
    • 📚题目内容
    • ✅解答
  • 🎯三数之和
    • 📚题目内容
    • ✅解答
  • 📝最后


在这里插入图片描述

📋前言

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


🎯两数之和 II

📚题目内容

给你一个下标从 1 开始的整数数组 numbers ,该数组已按非递减顺序排列,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1]numbers[index2] ,则 1 <= index1 < index2 <= numbers.length

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1index2

你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:27 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2]
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:24 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3]
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-10 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2]

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

  • 2 <= numbers.length <= 4
  • -1 <= numbers[i] <= 15
  • numbers 按非递减顺序排列。
  • -1 <= target <= 17
  • 仅存在一个有效答案。

✅解答

初始提供代码

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

答案
这题跟两数之和的题目还是差不多的思路的,但是要注意这题的要求和限制条件。我们可以在两数之和那一题的基础上继续修改,注意看题目说到的 “下标从 1 开始” ,因此我们在返回下标地址的时候要留意。代码如下。

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

这个解法实现了暴力枚举法来解决数组两数之和的问题,时间复杂度为 O(n^2)。具体来说,它双重循环遍历数组,将每一对不同的元素相加,判断它们的和是否等于目标数 target,如果相等,则找到了答案,返回两个元素的下标即可。虽然暴力枚举法思路简单,但时间复杂度较高,因此我们可以用双指针的方法来解这一题。

另一种解法

function twoSum2(numbers, target) {
    let left = 0, right = numbers.length - 1;
    while (left < right) {
        const sum = numbers[left] + numbers[right];
        if (sum < target) {
            left++;
        } else if (sum > target) {
            right--;
        } else {
            return [left + 1, right + 1]; 
        }
    }
}

因为数组已按照非递减顺序排列,所以可以考虑使用双指针分别从数组的两端开始向中间移动,每次比较两个指针所指的元素之和与目标数 target 的大小关系,如果和小于 target,则左指针右移,使得和增大;如果和大于 target,则右指针左移,使得和减小;如果和等于 target,则找到了答案,返回两个指针的下标即可。

具体的实现细节如下:

  • 定义左指针 left 和右指针 right,初始时分别指向数组的第一个元素和最后一个元素;
  • left < right 时,若 numbers[left] + numbers[right] < target,则将 left++(因为数组已按照非递减顺序排列,所以左指针右移可以使得和增大);若 numbers[left] + numbers[right] > target,则将 right--(同样理由,右指针左移可以使得和减小);若 numbers[left] + numbers[right] == target,则找到了答案,返回 [left, right]

该函数的时间复杂度为 O(n) ,其中 n 是数组的长度,因为在最坏情况下需要遍历整个数组一次。空间复杂度为 O(1),这个解法优于第一种暴力枚举的解法,只不过算法题练习,能解开,有思路都是可以的。


🎯移除元素

📚题目内容

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

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

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

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
输入: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 <= 8
  • 0 <= nums[i] <= 4
  • 1 <= val <= 3

✅解答

初始提供代码

function removeElement(nums, val) {
  // 补充代码
}

答案

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

这一题可以使用双指针来解决。首先定义两个指针 i 和 j,初始时都指向数组的第一个元素。然后遍历整个数组,如果当前元素不等于要移除的元素,则将其放到数组前面,即将 nums[j] = nums[i],并同时将 j 右移一位,表示下一个非要移除的元素需要存放的位置。遍历完成后,j 的值就是新数组的长度,因为 0 到 j - 1 就是新数组中的元素,而 j 到最后都是多余的。最后,返回 j 即可。

该函数的时间复杂度为 O(n),其中 n 是数组的长度。遍历一次数组,时间复杂度是 O(n)。空间复杂度为 O(1)。只使用了常数个变量,符合题目的要求。


接下来两题要会员了,所以题目源自 leetcode(题目考法基本是一样的)

🎯有序数组的平方

📚题目内容

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

示例一:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例二:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示与限制:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序。

进阶:
请你设计时间复杂度为 O(n) 的算法解决本问题

✅解答

初始提供代码

var sortedSquares = function(nums) {

};

答案

var sortedSquares = function(nums) {
    let n = nums.length;
    let res = new Array(n);
    let left = 0, right = n - 1;  // 双指针,分别指向数组左右两端
    for (let i = n - 1; i >= 0; i--) {  // 从后往前遍历
        if (Math.abs(nums[left]) > Math.abs(nums[right])) {  // 左指针指向的元素平方大
            res[i] = nums[left] * nums[left];
            left++;
        } else {  // 右指针指向的元素平方大
            res[i] = nums[right] * nums[right];
            right--;
        }
    }
    return res;
};

在这里插入图片描述
这道题可以用双指针来解,首先定义数组 res,存放最终结果。然后定义两个指针 left 和 right,分别指向数组的左端和右端。从后往前遍历数组,每次比较左指针指向的元素平方值和右指针指向的元素平方值的大小,将较大的值放入结果数组的末尾,并将对应的指针移动到下一个位置。直到遍历完整个数组,返回结果数组即可。

这样做的原因是因为,当数组中的元素都为正数时,平方后元素值会变大;当数组中的元素都为负数时,平方后元素值仍然变大,但是由于数组是按非递减顺序排好序的,因此无需再做一次排序操作。

该函数的时间复杂度是 O(n),其中 n 是数组的长度,符合题目要求。


🎯三数之和

📚题目内容

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例一:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1][-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例二:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0

示例三:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0

提示与限制:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

✅解答

初始提供代码

var threeSum = function(nums) {

};

答案

var threeSum = function(nums) {
    let res = [];
    nums.sort((a, b) => a - b); // 先对数组进行排序,方便去重和缩小搜索范围
    let n = nums.length;
    for (let i = 0; i < n; i++) {
        if (nums[i] > 0) {  // 如果当前值大于0,则三数之和一定大于0
            break;
        }
        if (i > 0 && nums[i] === nums[i-1]) {  // 去重,如果当前值与前一个值相同,则直接跳过
            continue;
        }
        let left = i + 1, right = n - 1;  // 定义双指针,分别指向当前值的下一个数和数组的右端
        while (left < right) {  // 左右指针向中间靠近
            let sum = nums[i] + nums[left] + nums[right];  // 计算当前三数之和
            if (sum === 0) {  // 如果满足条件,将结果放入结果集中
                res.push([nums[i], nums[left], nums[right]]);
                while (left < right && nums[left] === nums[left+1]) {  // 去重,如果左指针指向的元素与下一个元素相同,则向右移动指针
                    left++;
                }
                while (left < right && nums[right] === nums[right-1]) {  // 去重,如果右指针指向的元素与前一个元素相同,则向左移动指针
                    right--;
                }
                left++;
                right--;
            } else if (sum < 0) {  // 如果三数之和小于0,则将左指针向右移动一位
                left++;
            } else {  // 如果三数之和大于0,则将右指针向左移动一位
                right--;
            }
        }
    }
    return res;
};

这题思路是先对数组进行排序,然后将三数之和为 0 的组合找出来。外层循环遍历数组中的每一个数,内层循环使用双指针来找出与当前数相加为 0 的另外两个数。找到之后将符合条件的组合放入结果集中。由于数组已经排序并且去重,因此双指针搜索的范围会越来越小,时间复杂度为 O(n^2)

需要注意的是,在查找三数之和为 0 的时候,可以直接判断当前值是否大于 0,如果是,则说明后面的数不可能组成三数之和为 0,因此直接退出循环即可。同时,如果当前值与前一个值相同,也可以直接跳过,避免重复计算。

leetcode 示例代码

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    let res = [];
    if(nums.length < 3){
        return res
    }
    if(nums.length === 3){
        if(nums[0] + nums[1] + nums[2] === 0) {
            res.push([nums[0],nums[1],nums[2]])
            return res
        }else{
            return res
        }
    }

    nums.sort((a, b) => a - b);
    const len = nums.length;
    for(let i = 0;i < nums.length;i++){
        if(nums[i] > 0) break;
        if(i > 0 && nums[i] == nums[i-1]) continue;
        let L = i + 1;
        let R = len - 1;
        while(L < R) {
            const sum = nums[i] + nums[L] + nums[R];
            if(sum == 0){
                res.push([nums[i],nums[L],nums[R]]);
                while (L < R && nums[L] === nums[L+1]) L++; 
                while (L < R && nums[R] === nums[R-1]) R--; 
                L++;
                R--;
            }
            else if (sum < 0) L++;
            else if (sum > 0) R--;
        }
    }

    return res
};

在这里插入图片描述


📝最后

感谢阅读到这,这就是 Day3 的全部内容了,这个系列暂时离开一会,因为蓝桥云课接下来的题目都是要会员才能看,因此后续内容将转战到 leetcode 的题目发布为标准,那么这三天的数组内容也先告一段落了。文章内容中题目的答案都是通过检测的了,如果有疑问和争议的内容,可以评论区留言和私信我,收到消息第一时间解答和回复。
在这里插入图片描述

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

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

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

相关文章

混沌演练实践(二)-支付加挂链路演练 | 京东云技术团队

1. 背景 当前微服务架构下&#xff0c;各个服务间依赖高&#xff0c;调用关系复杂&#xff0c;业务场景很少可以通过一个系统来实现&#xff0c;常见的业务场景实现基本涉及多个上下游系统&#xff0c;要保证整体链路的稳定性&#xff0c;需要尽量减少系统之间的耦合性&#x…

Elasticsearch与Clickhouse数据存储对比 | 京东云技术团队

1 背景 京喜达技术部在社区团购场景下采用JDQFlinkElasticsearch架构来打造实时数据报表。随着业务的发展Elasticsearch开始暴露出一些弊端&#xff0c;不适合大批量的数据查询&#xff0c;高频次分页导出导致宕机、存储成本较高。 Elasticsearch的查询语句维护成本较高、在聚…

CloudBase CMS的开发注意事项

引言 在进行基于云开发的微信小程序开发时为了减轻工作量打算用CloudBase CMS来减轻工作量&#xff0c;随后去了解并体验了CloudBase CMS的使用&#xff0c;总体来说还有些许问题没有解决&#xff0c;对减轻后台管理工作并没有起到很大的作用。 项目情景 使用CloudBase CMS来管…

Flutter 笔记 | Flutter 基础组件

Text Text 用于显示简单样式文本&#xff0c;它包含一些控制文本显示样式的一些属性&#xff0c;一个简单的例子如下&#xff1a; Text("Hello world",textAlign: TextAlign.left, );Text("Hello world! Im Jack. "*4,maxLines: 1,overflow: TextOverflo…

HACKABLE: III

文章目录 HACKABLE: III实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、查看网站源码4、扫描目录5、访问网址6、查看并下载7、访问网站8、查看文件9、解密10、访问网站11、访问网站12、查看文件13、解密14、访问网站15、访问网站16、下载图片17、隐写1…

tcp连接阿里云linux服务器失败

原因&#xff1a; 自己程序bind的是127.0.0.1 应该改成 bind 阿里云的私网地址 client连接的是阿里云公网地址 参考&#xff1a; 阿里云服务器&#xff0c;客户端socket无法连接的问题 - 爱码网 排查过程记录&#xff1a; 1&#xff0c;安全组设置&#xff1a;有正常设置…

【C++】 模板(泛型编程、函数模板、类模板)

文章目录 模板泛型编程概念 函数模板常规使用显式指定及默认值多模板参数模板函数的声明和定义用函数模板优化冒泡排序 类模板常规使用显式指定及默认值多模板参数类中成员函数的定义和声明嵌套的类模板1.类和类型都能确定2.类和类型都不能确定3.类能确定&#xff0c;类型不确定…

Unity3D下如何实现跨平台低延迟的RTMP、RTSP播放

技术背景 好多开发者&#xff0c;希望我们能探讨下Unity平台RTMP或RTSP直播流数据播放和录制相关的模块&#xff0c;实际上&#xff0c;这块流程我们已经聊过多次&#xff0c;无非就是通过原生的RTMP或者RTSP模块&#xff0c;先从协议层拉取到数据&#xff0c;并解包解码&…

常用的表格检测识别方法——表格结构识别方法(上)

第三章 常用的表格检测识别方法 3.2表格结构识别方法 表格结构识别是表格区域检测之后的任务&#xff0c;其目标是识别出表格的布局结构、层次结构等&#xff0c;将表格视觉信息转换成可重建表格的结构描述信息。这些表格结构描述信息包括&#xff1a;单元格的具体位置、单元格…

子网掩码计算方法

子网掩码是用来划分网络的一种方式&#xff0c;它是一个32位的二进制数&#xff0c;用于将IP地址分成网络地址和主机地址两部分。子网掩码中的1表示网络地址&#xff0c;0表示主机地址。计算子网掩码的方式取决于需要划分的网络数量和主机数量。 以下是一些计算子网掩码的示例…

【LeetCode热题100】打卡第2天:两数相加

两数相加 ⛅前言 大家好&#xff0c;我是知识汲取者&#xff0c;欢迎来到我们的LeetCode热题100刷题专栏&#xff01; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练…

【2】tensorflow基本概念及变量函数

目录 1 tensorflow运行机制 1.1 搭建计算图模型 计算图的概念 计算图的使用 新建计算图 1.2 在会话中执行计算图 会话的启动方式 1.3 指定计算图的运行设备 2 tensorflow数据模型 2.1 认识张量及属性 张量的类型 张量的阶 2.2 张量类型转换和形状变换 张量类型转换 张…

TwinCAT ENI 数据详解

使用倍福TwinCAT工具可以生成ENI&#xff0c;先对ENI的cyclic frame数据进行解释说明 需要提前了解EtherCAT报文格式&#xff0c;可参考下面文章 EtherCAT报文格式详解_ethercat listtype 1_EtherCat技术研究的博客-CSDN博客https://blog.csdn.net/gufuguang/article/details/…

理解HAL_UARTEx_ReceiveToIdle_IT的工作过程

先只看没错误发生, 没开DMA时候的情况 将会面临3种结局, 收满数据时候IDLE正好发生, 数据发多了, 数据已经收满时候IDLE还没发生IDLE发生了数据没收满, 首先: 接收开始 主要的动作是 1. status UART_Start_Receive_IT(huart, pData, Size); 开始中断接口 2.…

【国产虚拟仪器】基于 ZYNQ 的电能质量系统高速数据采集系统设计

随着电网中非线性负荷用户的不断增加 &#xff0c; 电能质量问题日益严重 。 高精度数据采集系统能够为电能质 量分析提供准确的数据支持 &#xff0c; 是解决电能质量问题的关键依据 。 通过对比现有高速采集系统的设计方案 &#xff0c; 主 控电路多以 ARM 微控制器搭配…

1992-2022年经过矫正的夜间灯光数据

夜间灯光数据是我们在各项研究中经常使用的数据&#xff01;我们平时使用的夜间灯光数据主要来源于NPP/VIIRS和DMSP/OLS两种渠道&#xff0c;我们之前也分享过这两种来源的夜间灯光数据&#xff0c;包括&#xff1a; 2012-2021年逐年的NPP/VIIRS夜间灯光数据2012-2021年逐月的…

MySQL查询性能优化之索引覆盖、索引下推、索引潜水、索引合并

索引覆盖 什么是索引覆盖 select的数据列只用从索引中就能够取得&#xff0c;不必读取数据行&#xff0c;换句话说查询列要被所建的索引覆盖。 如何实现索引覆盖&#xff1f; 最常见的方法就是&#xff1a;将被查询的字段&#xff0c;建立到联合索引&#xff08;如果只有一…

python---变量(2)

此处&#xff0c;首次使用“”对a进行设置值&#xff0c;也就是对a的初始化。 后续位置对a使用“”&#xff0c;实际上是对a赋值。 因此两行代码得到的结果显然是不同的&#xff01; 变量的种类 1.整数-int-根据数据大小自动扩容 python中的变量类型不需要显示声明&#…

关于 arduino 中的 constrain(x, a, b)函数

当我们需要将一个变量的值限制在某个范围内时&#xff0c;可以使用 constrain(x, a, b) 函数来实现。该函数可以将参数 x 的值限制在区间 [a, b] 之间&#xff0c;如果 x 小于 a&#xff0c;则返回 a&#xff0c;如果 x 大于 b&#xff0c;则返回 b&#xff0c;否则返回 x。下面…

第五篇、基于Arduino uno,获取超声波(HC04)传感器的距离数据——结果导向

0、结果 说明&#xff1a;先来看看串口调试助手显示的结果&#xff0c;显示的是一个距离值&#xff0c;如果是你想要的&#xff0c;可以接着往下看。 1、外观 说明&#xff1a;虽然超声波传感器形态各异&#xff0c;但是原理和代码都是适用的。 2、连线 说明&#xff1a;只…