Given two strings S
and T
, return if they are equal when both are typed into empty text editors. #
means a backspace character.html
Example 1:git
Input: S = "ab#c", T = "ad#c" Output: true Explanation: Both S and T become "ac".
Example 2:github
Input: S = "ab##", T = "c#d#" Output: true Explanation: Both S and T become "".
Example 3:c#
Input: S = "a##c", T = "#a#c" Output: true Explanation: Both S and T become "c".
Example 4:函数
Input: S = "a#c", T = "b" Output: false Explanation: S becomes "c" while T becomes "b".
Note:spa
1 <= S.length <= 200
1 <= T.length <= 200
S
and T
only contain lowercase letters and '#'
characters.Follow up:指针
O(N)
time and O(1)
space?
这道题给了咱们两个字符串,里面可能会有井号符#,这个表示退格符,键盘上的退格键咱们应该都很熟悉吧,当字打错了的时候,确定要点退格键来删除的。固然也能够连续点好几下退格键,这样就能够连续删除了,在例子2和3中,也确实能看到连续的井号符。题目搞懂了以后,就开始解题吧,博主最早想的方法就是对S和T串分别处理完退格操做后再进行比较,那么就可使用一个子函数来进行字符串的退格处理,在子函数中,咱们新建一个结果 res 的空串,而后遍历输入字符串,当遇到退格符的时候,判断若结果 res 不为空,则将最后一个字母去掉;若遇到的是字母,则直接加入结果 res 中便可。这样S和T串同时处理完了以后,再进行比较便可,参见代码以下:code
解法一:htm
class Solution { public: bool backspaceCompare(string S, string T) { return helper(S) == helper(T); } string helper(string str) { string res = ""; for (char c : str) { if (c == '#') { if (!res.empty()) res.pop_back(); } else { res.push_back(c); } } return res; } };
咱们也能够不使用单独的子函数,而是直接用 for 循环来处理S和T串,固然原理都是同样的,分别创建s和t的空串,而后进行退格操做,最后比较s和t串是否相等便可,参见代码以下:blog
解法二:
class Solution { public: bool backspaceCompare(string S, string T) { string s = "", t = ""; for (char c : S) c == '#' ? s.size() > 0 ? s.pop_back() : void() : s.push_back(c); for (char c : T) c == '#' ? t.size() > 0 ? t.pop_back() : void() : t.push_back(c); return s == t; } };
这道题的 follow up 让咱们使用常数级的空间复杂度,就是说不能新建空的字符串来保存处理以后的结果,那么只能在遍历的过程当中同时进行比较,只能使用双指针同时遍历S和T串了。咱们采用从后往前遍历,由于退格是要删除前面的字符,因此倒序遍历要好一些。用变量i和j分别指向S和T串的最后一个字符的位置,而后还须要两个变量 cnt1 和 cnt2 来分别记录S和T串遍历过程当中连续出现的井号的个数,由于在连续井号后,要连续删除前面的字母,如何知道当前的字母是不是须要删除,就要知道当前还没处理的退格符的个数。好,如今进行 while 循环,条件是i和j至少有一个要大于等于0,而后对S串进行另外一个 while 循环,条件是当i大于等于0,且当前字符是井号,或者 cnt1 大于0,若当前字符是退格符,则 cnt1 自增1,不然 cnt1 自减1,而后i自减1,这样就至关于跳过了当前的字符,不用进行比较。对T串也是作一样的 while 循环处理。以后若i和j有一个小于0了,那么能够根据i和j是否相等的状况进行返回。不然再看若S和T串当前的字母不相等,则返回 false,由于当前位置的退格符已经处理完了,剩下的字母是须要比较相等的,若不相等就能够直接返回 false 了。最后当外层的 while 循环退出后,返回i和j是否相等,参见代码以下:
解法三:
class Solution { public: bool backspaceCompare(string S, string T) { int i = (int)S.size() - 1, j = (int)T.size() - 1, cnt1 = 0, cnt2 = 0; while (i >= 0 || j >= 0) { while (i >= 0 && (S[i] == '#' || cnt1 > 0)) S[i--] == '#' ? ++cnt1 : --cnt1; while (j >= 0 && (T[j] == '#' || cnt2 > 0)) T[j--] == '#' ? ++cnt2 : --cnt2; if (i < 0 || j < 0) return i == j; if (S[i--] != T[j--]) return false; } return i == j; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/844
参考资料:
https://leetcode.com/problems/backspace-string-compare/