给定两个字符串 S 和 T,如果它们在空文本编辑器中输入时相等,则返回。 # 表示退格字符

Posted

技术标签:

【中文标题】给定两个字符串 S 和 T,如果它们在空文本编辑器中输入时相等,则返回。 # 表示退格字符【英文标题】:Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character 【发布时间】:2020-07-21 23:34:09 【问题描述】:
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".
class Solution 
    public boolean backspaceCompare(String S, String T) 

        Stack<Character> stack1 = new Stack<Character>();
        Stack<Character> stack2 = new Stack<Character>();
        for(int i=0;i<S.length();i++)


            if(S.charAt(i)!='#')
            stack1.push(S.charAt(i));

        else
                    stack1.pop();
                
        
        for(int j =0;j<T.length();j++)

            if(T.charAt(j)!='#')
            stack2.push(S.charAt(j));

        else 
                stack2.pop();
        

        if(stack1==stack2)
            return true;
        return false;
    

我的输出是假的,答案应该是真的为什么这不起作用?

【问题讨论】:

你为什么要在if之前推字符? 顺便说一句,您应该创建函数来规范化字符串,而不是为每个输入重复代码。 另外,if (cond) return true; else return false; 可以简单地为return cond; 代码很难阅读,也很容易被误解,因为缩进很可怕。请编辑代码并修复它。 你的输出是假的,因为if(stack1==stack2) 永远不会是真的。比较使用equals(),而不是==,即return stack1.equals(stack2); 【参考方案1】:

第一个错误是将堆栈中的所有字符压入 if 语句之外。

您还应该在从中删除项目之前检查堆栈是否为空。 否则抛出 EmptyStackException。

// stack1.push(S.charAt(i)); <-- remove this line
if (S.charAt(i)!='#') 
   stack1.push(S.charAt(i));
else if (!stack1.isEmpty())  // <-- add this check
   stack1.pop();

第二个错误是不能用 == 比较两个栈的内容,改用 .equals 方法:

if(stack1.equals(stack2))

【讨论】:

运行时错误消息 java.util.EmptyStackException 在第 102 行,java.base/java.util.Stack.peek 在第 84 行,java.base/java.util.Stack.pop 在第 13 行,解决方案.backspaceCompare 在第 57 行,DriverSolution.__helper__ 在第 87 行,Driver.main 最后执行的输入:“a##c”“#a#c” leetcode.com/explore/featured/card/30-day-leetcoding-challenge/… 是的,在已经为空的文本字段中退格没有任何作用 - 您需要为此添加一项额外检查,请参阅更新 运行时错误消息:java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:8 在第 48 行,java.base/java.lang.StringLatin1.charAt 在第 709 行,java.base/java。 lang.String.charAt 在第 19 行,Solution.backspaceCompare 在第 57 行,DriverSolution.__helper__ 在第 87 行,Driver.main 最后执行的输入:“xywrrmp”“xywrrmu# p" 你的第二个循环从 S 读取字符,应该是 T:stack2.push(S.charAt(j))【参考方案2】:

Answer by Joni 正确解决了代码中的错误,但我还想解决一些其他问题:

您应该使用辅助方法来消除重复相同的代码。

您应该使用Deque 而不是Stack。 javadoc是这么说的。

我建议不要使用Stack/Deque,而是使用StringBuilder,以避免将char 值装箱。

类似这样的:

public boolean backspaceCompare(String s, String t) 
    return applyBackspace(s).equals(applyBackspace(t));


private static String applyBackspace(String s) 
    StringBuilder buf = new StringBuilder();
    for (int i = 0; i < s.length(); i++) 
        if (s.charAt(i) != '#')
            buf.append(s.charAt(i));
        else if (buf.length() != 0)
            buf.setLength(buf.length() - 1);
    
    return buf.toString();

【讨论】:

【参考方案3】:

您的想法可行,但是将字符串复制到堆栈中既昂贵又不必要。如果您从最后开始向后工作,则不需要额外的存储空间:

//given the string length or a valid character position, return
//the position of the previous valid character, or -1 if none
public static int previousCharPos(String s, int pos)

    int bs=0; // number of backspaces to match
    while(pos>0) 
        --pos;
        if (s.charAt(pos)=='#') 
            ++bs;
         else if (bs <= 0) 
            return pos;
         else 
            --bs;
        
    
    return -1;


public static boolean backspaceCompare(String S, String T)

    int spos = previousCharPos(S,S.length());
    int tpos = previousCharPos(T,T.length());
    while(spos >= 0 && tpos >= 0) 
        if (S.charAt(spos) != T.charAt(tpos)) 
            return false;
        
        spos = previousCharPos(S,spos);
        tpos = previousCharPos(T,tpos);
    
    return spos == tpos;

【讨论】:

以上是关于给定两个字符串 S 和 T,如果它们在空文本编辑器中输入时相等,则返回。 # 表示退格字符的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题(143)~比较含退格的字符串

leetcode刷题十二

844. 比较含退格的字符串

844. 比较含退格的字符串

844. 比较含退格的字符串

844. 比较含退格的字符串