【问题标题】:Optimized solution for Balanced Parentheses Problem平衡括号问题的优化解决方案
【发布时间】:2019-07-19 18:11:14
【问题描述】:

给定一个仅包含字符 '('')''{''}''['']' 的字符串,确定输入字符串是否有效。

输入字符串在以下情况下有效:

  1. 左括号必须用相同类型的括号括起来。
  2. 开括号必须以正确的顺序闭合。
  3. 请注意,空字符串也被认为是有效的。

示例 1:

Input: "()[]{}"
Output: true
Example 2:

示例 2:

Input: "{[(])}"
Output: false

我对上述问题的解决方法是:

static boolean isPair(char left,char right){
        return left=='{' && right=='}' || left=='(' && right==')' || left=='[' && right==']'; 
    }
    public boolean isValid(String s) {
        Stack<Character> stack= new Stack<>();
        for(char ch: s.toCharArray()){
            if(ch=='(' || ch=='{' || ch=='['){
                stack.push(ch);
            }
            else{
                if(!stack.isEmpty() && isPair(stack.peek(),ch))
                    stack.pop();
                else
                    return false;
            }
        }
        return stack.isEmpty();
}

我在某处找到了更智能的解决方案,但无法理解。 代码如下:

public boolean isValid(String s) {
        Stack<Character> stack= new Stack<>();
        for(char ch: s.toCharArray()){
            if(ch=='(')
                stack.push(')');
            else if(ch=='{')
                stack.push('}');
            else if(ch=='[')
                stack.push(']');
            else if(stack.isEmpty() || stack.pop()!=ch)
                return false;
        }
        return stack.isEmpty();
}

请帮助我了解最后一个 else-if 块的工作原理。

【问题讨论】:

  • 您的堆栈包含未闭合的括号。第二个示例中的堆栈包含 expected 括号。最后一个else if 只是测试当前字符是预期的括号。
  • 为什么你认为这个解决方案是“优化的”?它针对什么进行了优化?
  • 我称它为优化只是因为内存使用量......我的代码的内存使用量是 34.4MB,而 LeetCode Platform 上的这个解决方案的内存使用量是 34.2MB。
  • @jigneshkumar 如果您使用StringBuilder(追加/删除)而不是Stack(推送/弹出),您可能会使用更少的内存,因为您将避免使用自动装箱值。
  • 另外:使用索引for循环和s.charAt(i)toCharArray()好,因为后者复制了字符串的char数组。

标签: java optimization stack


【解决方案1】:

您已经为所有opening 括号推送了closing bracket。因此,当右括号出现时,它将匹配堆栈顶部的字符。如果不匹配或堆栈为空。这意味着不平衡

else if(stack.isEmpty() || stack.pop()!=ch)
    return false;

当你到达这里时,你有一个bracket 作为 ch,但堆栈是空的,或者堆栈中的值与传入的字符不匹配。

所以,括号不平衡

【讨论】:

    【解决方案2】:

    它实际上与你自己的版本非常相似。

    主要区别在于您将左括号推入堆栈并在isPair 中检查堆栈顶部的左括号是否与您当前正在评估的右括号匹配。

    该解决方案通过将预期的右括号直接推入堆栈来跳过它,但在功能上它是相同的。

    最后一个if else 与您的else 完全相同:

    1. 如果stack.isEmpty()返回false
    2. 如果不为空且不匹配堆栈顶部的括号,则返回 false
    3. 否则会弹出顶部的支架

    对于情况 2,解决方案会弹出堆栈,而在您的情况下,您不会弹出堆栈,但略有不同。但是当函数返回时它不会改变任何东西,并且该堆栈将不再被使用。

    【讨论】:

      【解决方案3】:

      Javascript解决问题

      
      var isValid = function (s) {
          // Stack to store left symbols
          const leftSymbols = [];
          // Loop for each character of the string
          for (let i = 0; i < s.length; i++) {
              // If left symbol is encountered
              if (s[i] === '(' || s[i] === '{' || s[i] === '[') {
                  leftSymbols.push(s[i]);
              }
              // If right symbol is encountered
              else if (s[i] === ')' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '(') {
                  leftSymbols.pop();
              } else if (s[i] === '}' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '{') {
                  leftSymbols.pop();
              } else if (s[i] === ']' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '[') {
                  leftSymbols.pop();
              }
              // If none of the valid symbols is encountered
              else {
                  return false;
              }
          }
          return leftSymbols.length === 0;
      };
      

      【讨论】:

        猜你喜欢
        • 2019-10-22
        • 2020-03-24
        • 2020-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-06
        • 2010-10-04
        • 1970-01-01
        相关资源
        最近更新 更多