算法系列之数组里的双指针

文章目录

  • 算法系列之数组里的双指针
    • 快慢指针代替双重循环
      • 暴力解法
      • 快慢指针法
    • 用双指针来排序
      • 暴力解法
      • 双指针排序

算法系列之数组里的双指针

在数组和链表的算法中双指针常出现,这篇用两道题来看一下双指针在数组算法里的用处。

快慢指针代替双重循环

https://leetcode.cn/problems/remove-element/description/

题目:
给你一个数组 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,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

暴力解法

首先直接想暴力解法,因为题目中明说了我们不可以创建新的数组,所以我们考虑对数组本身做删除。又因为数组是连续存储空间,我们在删除一个数后,需要把它后面的都往前挪一个。这就很明显需要双重循环,也就是 O(n^2) 的时间复杂度。代码如下:

var removeElement = function(nums, val) {let valCount = 0;for (let i = 0; i < nums.length; i++) {if (nums[i] === val && i + valCount < nums.length) { valCount ++;for (let j = i; j < nums.length - 1; j++) {nums[j] = nums[j + 1];}i --; // 因为 i 后面的数都往前移了一位,i 也有新的数代替了,所以 i 这个位置也要重新判断。}}return nums.length - valCount; // 这里不用 valCount 也可以每次进入判断直接把数组后面的数 pop 出去,直接缩小数组。(用 pop 比这种方法更耗时)
}

快慢指针法

可不可以变成 O(n) 的时间复杂度,也就是一遍循环搞定呢。这里就可以巧用快慢指针的思想。
快指针每次向后移动一位,判断当前值是不是要排除的值。

  • 是排除值则慢指针不变,快指针继续往后移动。
  • 不是排除值说明要保留,就放到慢指针指向的位置,慢指针也往后移动一位。

这样可以保证慢指针范围内的都是需要保留的数组。

var removeElement = function(nums, val) {let lIndex = 0, rIndex = 0;while(rIndex < nums.length) {if (nums[rIndex] !== val) {nums[lIndex++] = nums[rIndex++];} else {rIndex ++;}}return lIndex;
};

在这里插入图片描述

用双指针来排序

https://leetcode.cn/problems/squares-of-a-sorted-array/description/

题目:
给你一个按 非递减顺序 排序的整数数组 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]

暴力解法

先平方,再进行排序,sort底层是快排,所以时间复杂度是 O(n + nlogn)

function sortedSquares(nums: number[]): number[] {return nums.map((item: number) => item * item).sort((a, b) => a - b);
};

双指针排序

暴力解法没有用到本来就是排序数组这个特点。因为本来排序过,所以最大的肯定在两端,约往中间越小,我们定义两个指针从左右边界开始往内部移动,移动中比较左右哪个的平方比较大就先加入结果数组并进行移动。
只进行了一次遍历,时间复杂度是 O(n)。

function sortedSquares(nums: number[]): number[] {const res = [];let lIndex = 0, rIndex = nums.length - 1;while (lIndex !== rIndex) {if (nums[lIndex] ** 2 < nums[rIndex] ** 2) {res.unshift(nums[rIndex] ** 2);rIndex --;} else {res.unshift(nums[lIndex] ** 2);lIndex ++;}}res.unshift(nums[lIndex] ** 2);return res;
};

在这里插入图片描述

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

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

相关文章

嵌入式3-29

今日作业&#xff1a;用fwrite 和 fseek功能&#xff0c;将一张bmp格式的图片更改成 德国国旗#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> typedef unsigned char bgr[3]; int main(int argc, const char *argv[])…

安装docker 并搭建出一颗爱心树

1、docker介绍 Docker 是⼀个开源的容器运⾏时软件&#xff08;容器运⾏时是负责运⾏容器的软件&#xff09;&#xff0c;基于 Go 语 ⾔编写&#xff0c;并遵从 Apache2.0 协议开源。 Docker可以让开发者打包⾃⼰的应⽤以及依赖到⼀个轻量的容器中&#xff0c;然后发布到任何…

开源大数据集群部署(十九)Hbase部署

作者&#xff1a;櫰木 1 HBASE 安装部署 hbase组件部署主机HMasterhd1.dtstack.com,hd2.dtstack.comHRegionServerhd3.dtstack.com,hd2.dtstack.com,hd1.dtstack.com 2 创建hbase Kerberos主体 在每台机器上进行生成 bash /data/kerberos/getkeytabs.sh /etc/security/key…

Kaggle注册验证码问题(Captcha must be filled out.)

Kaggle注册验证码问题 Captcha must be filled out.使用Edge浏览器 Header Editor 插件安装 下载插件Header Editor 导入重定向脚本 点击扩展插件&#xff0c; 打开Header Editor插件&#xff0c;进行管理 点击导入输入下载链接进行下载或者导入本地json文件(二者任选其一…

OpenHarmony系统开发之应用接口文件转换工具介绍

简介&#xff1a; 应用接口文件转换工具是根据异构格式接口文件(.h 文件)转换生成 OpenHarmony 系统应用层需要的 TS(type-script)接口文件(*.d.ts)的工具。若某个服务实现方式为 c&#xff0c;且供应用层访问的接口已在.h 文件中定义&#xff0c;此时&#xff0c;NAPI 接口开…

OpenHarmony无人机MAVSDK开源库适配方案分享

MAVSDK 是 PX4 开源团队贡献的基于 MavLink 通信协议的用于无人机应用开发的 SDK&#xff0c;支持多种语言如 C/C、python、Java 等。通常用于无人机间、地面站与通信设备的消息传输。 MAVLink 是一种非常轻量级的消息传递协议&#xff0c;用于与无人机&#xff08;以及机载无…

目标检测评价标准

主要借鉴&#xff1a;https://github.com/rafaelpadilla/Object-Detection-Metrics?tabreadme-ov-file 主要评价指标、术语&#xff1a; Intersection Over Union (IOU)&#xff1a;两个检测框交集面积与并集面积的比值 True Positive (TP)&#xff1a;IOU大于阈值的检测框…

计算机网络——30SDN控制平面

SDN控制平面 SDN架构 数据平面交换机 快速、简单&#xff0c;商业化交换设备采用硬件实现通用转发功能流表被控制器计算和安装基于南向API&#xff0c;SDN控制器访问基于流的交换机 定义了哪些可以被控制哪些不能 也定义了和控制器的协议 SDN控制器&#xff08;网络OS&#…

计算机基础系列 —— 虚拟机代码翻译器(1)

“Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.” ―Linus Torvalds 文中提到的所有实现都可以参考&#xff1a;nand2tetris_sol&#xff0c;但是最好还是自己学习课程实现一…

Spring Cloud GateWay——网关的基本使用

1. 为什么所有的请求先到网关呢&#xff1f; 有了网关就可以对请求进行路由&#xff0c;路由到具体的微服务&#xff0c;减少外界对接微服务的成本&#xff0c;比如&#xff1a;400电话&#xff0c;路由的试可以根据请求路径进行路由、根据host地址进行路由等&#xff0c; 当微…

ios应用内支付

用uniapp开发iOS应用内支付 准备前端代码服务器端处理如果iOS支付遇到问题实在解决不了&#xff0c;可以联系我帮忙解决&#xff0c;前端后端都可以解决&#xff08;添加的时候一定要备注咨询iOS支付问题&#xff09; 准备前端代码 获取支付通道 (uni.getProvider) uni.getPr…

上岸美团了!

Hello&#xff0c;大家好&#xff0c;最近春招正在如火如荼&#xff0c;给大家分享一份美团的面经&#xff0c;作者是一份某双非的硕&#xff08;只如初见668&#xff09;&#xff0c;刚刚通过了美团的3轮面试&#xff0c;已经拿到offer&#xff0c;以下是他的一些分享。 一面&…