Hi 你们好,我是张小猪。欢迎来到『宝宝也能看懂』系列特别篇 - 30-Day LeetCoding Challenge。这是一个 leetcode 官方的小活动。能够在官网看到,从 4 月 1 号开始,天天官方会选出一道题,在 24 小时内完成便可得到一点小奖励。git
这里是 4 月 9 号的题,也是题目列表中的第 844 题 -- 『比较含退格的字符串』github
给定 S
和 T
两个字符串,当它们分别被输入到空白的文本编辑器后,判断两者是否相等,并返回结果。#
表明退格字符。shell
示例 1:c#
输入:S = "ab#c", T = "ad#c" 输出:true 解释:S 和 T 都会变成 “ac”。
示例 2:segmentfault
输入:S = "ab##", T = "c#d#" 输出:true 解释:S 和 T 都会变成 “”。
示例 3:数据结构
输入:S = "a##c", T = "#a#c" 输出:true 解释:S 和 T 都会变成 “c”。
示例 4:编辑器
输入:S = "a#c", T = "b" 输出:false 解释:S 会变成 “c”,但 T 仍然是 “b”。
提示:优化
1 <= S.length <= 200
1 <= T.length <= 200
S
和 T
只含有小写字母以及字符 '#'
。EASYspa
喵喵喵,直白而又干脆的题目。关键的核心点就是,'#' 表明的退格操做,行为是向左删除上一个字符,也就意味着左边的字符都是不稳定的。抓住这个点就可让咱们后续的实现简单不少。这里提供两种思路:指针
首先是第一种思路 -- 模拟退格。若是咱们本身控制逻辑来处理的话,多少会有点麻烦。因此这里直接借助了栈这个数据结构的特性,即后进先出,来方便的模拟退格的逻辑。具体流程以下:
基于以上流程,咱们只须要分别获取两个输入字符串的最终处理结果,而后进行比较便可。具体代码以下:
const decode = s => { const stack = []; for (const c of s) { c === '#' ? stack.pop() : stack.push(c); } return stack.join(''); }; const backspaceCompare = (s1, s2) => decode(s1) === decode(s2);
上面的方案存在额外的空间复杂度,那么咱们是否能够优化掉这一部分呢?咱们尝试一下这种从稳定字符开始处理的思路。
这种思路的核心就是,咱们每一步都去获取一个稳定的字符,而后进行比较便可。什么是稳定的字符?即不会由于还没处理的退格行为再发生变化的字符。那么相信小伙伴们很容易能想到,咱们能够从尾部开始处理,便不用对于历史内容进行储存了,也就能够优化掉额外的空间复杂度了。
具体流程以下:
false
。true
。const backspaceCompare = (s1, s2) => { let p1 = s1.length - 1; let p2 = s2.length - 1; while (p1 >= 0 || p2 >= 0) { for (let bs = 0; s1[p1] === '#' || bs > 0; --p1) { s1[p1] === '#' ? ++bs : --bs; } for (let bs = 0; s2[p2] === '#' || bs > 0; --p2) { s2[p2] === '#' ? ++bs : --bs; } if (s1[p1--] !== s2[p2--]) return false; } return true; }
第一种思路是一种比较典型的栈结构的应用场景,即咱们须要根据后面的数据来从新修改前面的内容。不知道看过以前小猪周赛题解的小伙伴们是否还记得,咱们曾经也遇到过很相似的逻辑。但愿能帮助小伙伴们识破这种套路!
若是以为不错的话,记得『三连』哦。小猪爱大家哟~