[LeetCode] 844. Backspace String Compare

Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character.

Example 1:

Input: S = "ab#c", T = "ad#c"
Output: true
Explanation: Both S and T become "ac".

Example 2:

Input: S = "ab##", T = "c#d#"
Output: true
Explanation: Both S and T become "".

Example 3:

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:

  1. <= S.length <= 200
  2. <= T.length <= 200
    S and T only contain lowercase letters and '#' characters.

Follow up:

  • Can you solve it in O(N) time and O(1) space?

这道题比较直观的解法是用stack,遇到不是#的字符就加入stack,遇到#,只要stack不为空就pop,最后比较新处理后的str就可以了。但是这么做的时间空间复杂度是O(M+N)

class Solution:
    def backspaceCompare(self, S: str, T: str) -> bool:
        return self.build(S) == self.build(T)
    
    def build(self, s: str) -> str:
        builder = []
        for c in s:
            if c != "#":
                builder.append(c)
            elif builder:
                builder.pop()
        return "".join(builder)

我试图用iteration的方式代替stack,但是因为str是immutable,所以要把str转换成list,这么做空间复杂度仍然是O(M+N)

class Solution:
    def backspaceCompare(self, S: str, T: str) -> bool:
        if not S and not T: return True
        if not S: return False
        if not T: return True
        
        s_post = self.construct_string(list(S))
        t_post = self.construct_string(list(T))
        return s_post == t_post
    
    def construct_string(self, s: list) -> str:
        replace = 0
        for i in range(len(s)):
            if s[i] == "#" and replace > 0:
                replace -= 1
            elif s[i] != "#":
                s[replace] = s[i]
                replace += 1
        
        return "".join(s[:replace])

最后这个解法比价巧妙,是从后往前比较。先用一个skip=0,然后如果遇到#,那么需要skip,所以skip就加一,如果skip大于yi,遇到非#的值就让skip减一。注意因为只要skip大于零就说明现在当前这个char需要被skip掉,如果skip为0,那么yeild当前的char,因为这个char会在最后的结果里,然后随时比较s和t的yield的值,只要有不一样就return False,否则最后return True
还要注意一些python特殊的写法,yeild是返回值但是不终止程序。itertools.zip_longest就是可以同时循环,并且fit最长的那个。all就是所有值

class Solution:
    def backspaceCompare(self, S: str, T: str) -> bool:
        return all(s == t for s, t in itertools.zip_longest(self.next_character(S), self.next_character(T)))
            
    
    def next_character(self, s: str) -> str:
        skip = 0
        for i in range(len(s)-1, -1, -1):
            if s[i] == "#":
                skip += 1
            elif skip > 0:
                skip -= 1
            else:
                yield s[i]
        

posted on 2020-04-10 05:19  codingEskimo  阅读(124)  评论(0编辑  收藏  举报

导航