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

news2024/11/17 13:48:42

在这里插入图片描述

  • 博主简介:努力学习的预备程序媛一枚~
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: 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 null
                    return false;
            }

            //指针后退,为下一次比较做准备
            pointerS--;
            pointerT--;
        }
        //大循环跳出,说明两者皆为空字符串,返回true
        return 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.coloradmin.cn/o/184342.html

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

相关文章

《收获,不止Oracle》表的连接学以致用

6.2 三大类型 6.2.1 连接类型 嵌套循环 排序合并及散列连接 第一种方式就是数据库表连接中的嵌套循环连接&#xff08;Nested Loops Join&#xff09;&#xff0c;而第二种方式就是表连接中的排序合并连接&#xff08;Merge Sort Join&#xff09;或者散列连接&#xff08;…

【SpringCloud】Gateway服务网关的基本使用

一、初识Gateway服务网关为什么需要网关&#xff1f;在微服务中&#xff0c;各个模块之间的调用&#xff0c;也可以称其为远程调用&#xff01;但是&#xff0c;如果是外部&#xff08;用户&#xff09;对微服务进行访问时&#xff0c;发的请求能不加处理的直接访问微服务吗&am…

使用Client Java构建Exporter程序

一、client_java client_java是Prometheus针对JVM类开发语言的client library库&#xff0c;我们可以直接基于client_java用户可以快速实现独立运行的Exporter程序&#xff0c;也可以在我们的项目源码中集成client_java以支持Prometheus。注意&#xff1a;Prometheus 提供的cl…

WordPress默认数据库中的12个数据表

WordPress 安装的时候数据库会有 12 张默认的数据表&#xff0c;每张表的数据都包含了 WordPress 不同的功能。看看这些表的结构&#xff0c;你能很容易的了解网站不同的部分都是存在哪里的。目前&#xff0c;默认的 WordPress 安装会创建如下12个数据表。表名描述wp_users您的…

大数据在5G应用场景下有哪些示范项目?

近期&#xff0c;贵州省2022年5G应用场景示范观摩会在贵阳召开&#xff0c;此次观摩会由贵州省大数据发展管理局、贵州省通信管理局主办。数据宝“基于5G技术的交通国有大数据治理多元应用”获得贵州省5G应用场景示范项目&#xff08;五星&#xff09;称号。 据悉&#xff0c;…

二叉树(二)

前言本章我们继续了解二叉树。上文我们对树和二叉树有了简单的了解&#xff0c;详见二叉树&#xff08;一&#xff09;这里我要解释一下为什么我们不对树进行增删查改呢&#xff1f;答案是&#xff1a;没有意义。我们更应该把有限的精力用作有意的地方&#xff0c;那么我们今天…

TLS协议。

IPSec通过安全关联实现IP分组安全关联两端之间的安全传输过程&#xff0c;TLS通过建立安全连接实现数据在两个应用进程之间的安全传输过程。TLS建立安全连接时&#xff0c;实现安全连接两端应用进程之间的双向身份鉴别过程&#xff0c;保证经过安全连接传输的数据的保密性和完整…

【GPLT 二阶题目集】L2-017 人以群分

社交网络中我们给每个人定义了一个“活跃度”&#xff0c;现希望根据这个指标把人群分为两大类&#xff0c;即外向型&#xff08;outgoing&#xff0c;即活跃度高的&#xff09;和内向型&#xff08;introverted&#xff0c;即活跃度低的&#xff09;。要求两类人群的规模尽可能…

时间序列模型

一、季节分解 1、概念 时间序列也称为动态序列&#xff0c;是指将某种现象的指标数值按照时间顺序排列而成的数值序列。主要由时间要素和数值要素构成。时期序列中&#xff0c;数值要素反映现象在一定时期内发展的结果&#xff1b;时点序列中&#xff0c;数值要素反映现象在一…

如何在FreeBSD中安装Nginx,MySQL,PHP(FEMP)

本文介绍如何在FreeBSD 13系统中安装Nginx、MySQL、和PHP服务。系统环境FreeBSD 13.0-RELEASE更新系统在安装任何软件之前更新系统是一个好习惯&#xff0c;以便检查系统更新&#xff1a;rootfreebsd:~ # freebsd-update fetchrootfreebsd:~ # freebsd-update install安装Nginx…

在线教育-谷粒学院学习笔记(九)

文章目录1 内容介绍2 搭建项目前台环境NUXT3 整合项目首页4 nuxt路由5 首页数据banner显示—初始配置6 首页数据banner显示—接口7 首页数据banner显示—前端实现8 首页数据显示—热门课程和名师9 Redis复习10 首页数据添加Redis缓存1 内容介绍 搭建项目前台系统环境 NUXT 整合…

【PHP 随记】—— Composer 安装及镜像配置

&#x1f449;总目录&#x1f448;\large\colorbox{skyblue}{&#x1f449;总目录&#x1f448;}&#x1f449;总目录&#x1f448;​ 文章目录1、Composer 安装2、配置镜像Composer 是 PHP 用来管理依赖&#xff08;dependency&#xff09;关系的工具&#xff1b;简单来说&…

等级保护介绍

等保流程 等级保护 等保发展历程 。1994 首次国家提出等级保护概念 。1999 针对信息系统保护有法律依据 。2007 等保1.0措施。 。2017 立法了《网络安全法》 。2019年 等保2.0 颁布 等保2.0和1.0有什么特点和区别 1.名称变了信息安全技术信息等级保护要求 改为 信息安全基础网络…

1、测试用例通用模板

一、针对大版本需求的测试用例模板 1、测试用例模板说明 1.1、表头说明 项目版本号V1.0--测试用例&#xff08;示例标题&#xff09;(xxxxx有限公司测试组/ONLY FOR INTERNAL USE ONLY)Confidentiality level 密级(xxxxxx测试组/仅供内部使用) Internal 内部公开 修订记录版…

软件设计(二)

软件设计&#xff08;一&#xff09;https://blog.csdn.net/ke1ying/article/details/128779601 11、windows系统当双击.jpg文件的时候&#xff0c;系统会通过建立的 文件关联 来决定使用什么程序来打开该图像文件。 &#xff08;双击.jpg文件&#xff0c;系统会建立‘window…

【哈希表】leetcode349. 两个数组的交集(C/C++/Java/Python/Js)

leetcode349. 两个数组的交集1 题目2 思路--set2.1 拓展/后记3 代码3.1 C版本3.2 C版本3.3 Java版本3.4 Python 版本3.5 JavaScript版本4 总结1 题目 题源链接 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考…

分享150个ASP源码,总有一款适合您

ASP源码 分享150个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 150个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1DpxbFxdGCl9eWEe3AaD1eA?pwdecqi 提取码&#x…

echarts数据可视化项目搭建(二)

目录主题设置默认主题重点示例自定义主题调色盘主题全局局部颜色渐变可视化图表自适应重点示例实现简单的加载动画重点示例增量动画实现重点示例简单动画配置项关于全局echarts对象和echartsInstance对象echarts.connect()其他echarts实例对象方法本博客内容参考黑马课程&#…

系统编程中的进程的概念No.2

引言&#xff1a; 今天是个好日子&#xff0c;日更动态养成习惯&#xff0c;日更博客你我他&#xff0c;北京时间 2023/1/29/10:09&#xff0c;今天阳光明媚&#xff0c;但是还是很冷&#xff0c;起床时间8:55&#xff0c;可以看出又早了那么一点点&#xff0c;今天为什么能起…

VSCode调试Python文件并指定虚拟环境

记录在使用VSCode调试py文件时遇到的一些问题&#xff1a;1.启用Debug模式进行调试2.调试带参数的python文件3. 调试时指定服务器虚拟环境4. 相对路径出错首先给出VScode 官方调试说明&#xff1a;https://code.visualstudio.com/docs/python/debugging#_set-configuration-opt…