【Leetcode每日一题】844. 比较含退格的字符串|重构字符串/双指针

news/2025/2/12 0:51:44/

在这里插入图片描述

  • 博主简介:努力学习的预备程序媛一枚~
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: LeetCode每日一题–进击大厂

前言:

昨天的【Leetcode每日一题】27. 原地移除元素|神级理解双指针一文中,生动形象的为大家讲解如何理解双指针,受到了很好的反馈,今天趁热打铁,瑶瑶子为大家带来一道双指针的plus版本题目,会比昨天的难一点,但是本质和逻辑是一样的(就是两个人干活,男女搭配,干活不累!)
在讲今天这道题目之前,推荐大家去做一下力扣283题目,这里给出链接和我的题解,和昨天27题非常类似,只有细小差别。
283. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。

class Solution1 {public void moveZeroes(int[] nums) {int quickIndex = 0;//快指针,用于遍历int slowIndex = 0;//慢指针用于挖坑for (; quickIndex < nums.length; quickIndex++) {if (nums[quickIndex] == 0) {continue;//遇见0就跳过}nums[slowIndex++] = nums[quickIndex];//慢指针在挖坑,等待快指针给过来的"萝卜"}for (; slowIndex < nums.length; slowIndex++)//慢指针把0填上去{nums[slowIndex] = 0;}}
}

目录

  • 前言:
  • 题目描述
  • 题目分析
    • 方法1:
    • 方法2

题目描述

链接:844. 比较含退格的字符串

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。

可以用 O(n) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?
(O(1)的复杂度会用方法2实现)

题目分析

方法1:

最容易想到的方法,也就是为两个字符串分别重写构造各自的新字符串,来存储删除后的两个新字符串。再把两个新字符串进行比较(非原地修改)

  • 设计一个方法,用于获取修改后的新字符串
  • 将两者对应删除空格后的新字符串进行比较

本质还是昨天所说的双指针,一个遍历,一个指向待插入位置(但是其实双指针我觉得,在这题当中,不是形式上的双指针,而是思想上的,需要体会,逻辑是完全一样

class Solution {public boolean backspaceCompare(String s, String t) {return newString(s).equals(newString(t));}//通过这个函数,得到退格后的新字符串(不含#的字符串)public String newString(String str) {StringBuffer ans = new StringBuffer();for (int i = 0; i < str.length(); i++) {if (str.charAt(i) != '#') {ans.append(str.charAt(i));//填入} else {if (ans.length() > 0) {ans.deleteCharAt(ans.length() - 1);//慢指针遇到#,就把萝卜拔掉,不前行}}}return ans.toString();//将StringBuffer类型转换为String类型返回}
}

本质是快慢指针法,在newString这个方法中对一个字符串的操作中体现体现

  • 时间复杂度O(N+M)
  • 空间复杂度O(N+M)

方法2

也是双指针,与方法1以及之前所讲的双指针不同的是:快慢两个指针作用在同一个字符串/数组上;而纯双指针,即两个指针分工明确,各不相同,作用在不同的字符串上/数组。

具体用代码来体现(瑶瑶子附有有保姆级详细注释)

class Solution {public boolean backspaceCompare(String s, String t) {int pointerS = s.length() - 1;//指针1号指向s字符串中的待比较元素int pointerT = t.length() - 1;//指针2号指向t字符串中的待比较元素while (pointerS >= 0 || pointerT >= 0) {//注意这里是||,为什么不是&&?举例:hhh 和 空,结果还是false//求出s字符串中第一个待比较元素int skipS = 0;int slipT = 0;while (pointerS >= 0) {if (s.charAt(pointerS) == '#') {skipS++;pointerS--;//向后遍历下一个元素} else if (skipS > 0) {//类似于“出栈”过程,出栈之前必须判断栈是否为空!pointerS--;skipS--;} else {//即skipS=0,元素不为'#'的情况-->找到待比较元素break;//跳出循环}}//同样的方法,找到t字符串中待比较元素while (pointerT >= 0) {if (t.charAt(pointerT) == '#') {slipT++;pointerT--;} else if (slipT > 0) {pointerT--;slipT--;} else {break;}}//比较两个循环中分别出来的字符if (pointerS >= 0 && pointerT >= 0) {if (s.charAt(pointerS) != t.charAt(pointerT)) {return false;}} else {if (pointerS >= 0 || pointerT >= 0)//一个字符串还存在字符待比较,另一个一个字符串的字符已经比较完:如:a nullreturn false;}//指针后退,为下一次比较做准备pointerS--;pointerT--;}//大循环跳出,说明两者皆为空字符串,返回truereturn true;}
}

易错点

  • 1:超出时间限制:每次循环比较字符后,没有让指针后退pointerS--;pointerT--
  • 2:指针越界异常(java.lang.StringIndexOutOfBoundsException: String index out of range: -1):在循环内,并不能保证pointerS和ponterT大于0,所以在进行charAt(pointerS)/charAt(pointerT)运算时,必须保证此时下标大于or等于0(if (pointerS >= 0 && pointerT >= 0))

方法2反思:
 双指针思想主要体现在pointerS和pointerB经过一些巧妙的处理while循环,指向各自字符串的待比较元素,并分别比较。
【重点】除了双指针思想;此题方法2:不得不学习的重点:
1. 对于删除空格,采用从后往前遍历方式
2. 巧妙利用计数器(skipS&skipT),记录指针所需要跳过的字符个数



write in the end:
后续还会更新很多双指针题目来加深对双指针的理解!以及持续更新Java刷题系列文章。还不快快关注![笔芯]

  • 专栏系列文章:
    【Leetcode每日一题】27. 原地移除元素|神级理解双指针
    【Leetcode每日一题】69. x 的平方根/Sqrt(x)|二分查找
    【Leetcode每日一题】34.在排序数组中查找元素的第一个和最后一 个位置|二分求下标

  • 建立此专栏的初衷是为了监督自己每天认真刷一个题,积少成多。并把自己每次刷题的思路、收获以博文的形式分享出来,帮助更多人,以及方便后续复习。如果有兴趣的同学可以订阅此专栏,我们一起刷题,一起交流,进步和学习!专栏:LeetCode每日一题–进击大厂

在这里插入图片描述


http://www.ppmy.cn/news/20556.html

相关文章

闭区间连续函数的性质+习题课(函数与极限总复习)——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天我们的内容依然是关于连续函数的概念和性质及相关内容&#xff0c;之前的博客我们学习到了函数的连续性和函数的间断点&#xff0c;那今天&#xff0c;我们便来看看闭区间上连续函数的性质&#xff0c;好的&#xff0c;接下来就让我们进…

注意力提示

人类的注意力是有限的、有价值和稀缺的资源。 受试者使用非自主性和自主性提示有选择性地引导注意力。前者基于突出性&#xff0c;后者则依赖于意识。 注意力机制与全连接层或者汇聚层的区别源于增加的自主提示。 由于包含了自主性提示&#xff0c;注意力机制与全连接的层或…

Python语法入门笔记(二)

一、六种最基础的数据类型 1.type type(变量):可以返回变量的数据类型 a=10 print(type(a))#打印a的数据类型 2.数字类型 2.1.int类型(py中不用定义类型,可以直接用) a=10 2.2.py浮点型只有float a=1.00 print(a) print(type(a)) 2.3.complex复数类型 类似于高中学过的复数 注…

HTTP协议学习

一、http请求协议1、常见请求头accept:浏览器通过这个头告诉服务器&#xff0c;它所支持的数据类型Accept-Charset: 浏览器通过这个头告诉服务器&#xff0c;它支持哪种字符集Accept-Encoding&#xff1a;浏览器通过这个头告诉服务器&#xff0c;支持的压缩格式Accept-Language…

ip-guard如何让计算机按照计算机名进行自动分组?

适用场景 当客户端机器的计算机名称是按照一定规律命名区分不同部门时,适合按照计算机名进行自动分组。 设置方法 在oserver.ini上增加以下配置保存后立即生效: [AGENTGROUP] 组名称1=AGTNAME:前缀* 组名称2=AGTNAME:*字段*

RocketMq-dashboard:topic 5min trend 原理和源码分析(一)

本文阅读基础&#xff1a;使用或了解过rocketMq&#xff1b;想了解"topic 5min trend"背后的原理&#xff1b;想了解监控模式如何实现。RocketMq的dashboard&#xff0c;有运维页面&#xff0c;驾驶舱&#xff0c;集群页面&#xff0c;主题页面&#xff0c;消费者页面…

Python中的迭代器与生成器

Python中的迭代器与生成器在Python中存在两种好用的功能&#xff1a;迭代器与生成器。以list容器为例&#xff0c;在使用该容器迭代一组数据时&#xff0c;必须事先将所有数据存储到容器中&#xff0c;才能开始迭代&#xff1b;而生成器却不同&#xff0c;它可以实现在迭代的同…

帮助粉丝用青泥学术大数据推荐毕业论文选题(围绕 教育信息化2.0、疫情期间线上学习质量问题、Steam教育、智慧教育等突破点来抉择)

需求 本科论文水平&#xff0c;青泥学术可以起到一定帮助。 说明 我也只是读了一个学期的硕士而已&#xff0c;谈不上多高的指点&#xff0c;可能比一些人更努力一些。 所以我的学术造诣不算太高&#xff0c;不敢盲目建议。 但是君子性非异也&#xff0c;善假于物也。 我借…