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; }
第一種思路是一種比較典型的棧結構的應用場景,即咱們須要根據後面的數據來從新修改前面的內容。不知道看過以前小豬周賽題解的小夥伴們是否還記得,咱們曾經也遇到過很相似的邏輯。但願能幫助小夥伴們識破這種套路!
若是以爲不錯的話,記得『三連』哦。小豬愛大家喲~