【问题标题】:Check for Valid Parentheses in java在java中检查有效的括号
【发布时间】:2018-05-21 15:25:28
【问题描述】:

我试图找出给定的输入是否是有效的括号。输入字符串由 '(', ')', '{', '}', '[' and ']' 组成。
输入字符串在以下情况下有效:

1.开括号必须用相同类型的括号括起来。
2.开括号必须以正确的顺序闭合。 3.空字符串有效

但是,我下面使用递归的代码不适用于有效情况。假设转到基本情况(当输入为“”时),而是转到 for 循环之后的 return 语句。

class Solution {

    public boolean validParen(String input) {

        if(input.isEmpty()) {
            return true;
        }

        else {
            for (int i = 0; i < input.length() - 1; i++) {
                if ((input.charAt(i) == '(' && input.charAt(i + 1) == ')') ||
                        (input.charAt(i) == '{' && input.charAt(i + 1) == '}') ||
                        (input.charAt(i) == '[' && input.charAt(i + 1) == ']')) {
                    input = input.substring(0, i) + input.substring(i + 2);
                    System.out.println("Input is " + input);
                    validParen(input);
                }
            }
            return false;
        }
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        //System.out.println(sol.validParen("")); 
        //System.out.println(sol.validParen("()")); // returns false for some reason 
        //System.out.println(sol.validParen("()[]{}")); // returns false for some reason
        //System.out.println(sol.validParen("(]"));
        //System.out.println(sol.validParen("([)]"));
        //System.out.println(sol.validParen("{[]}")); // returns false for some reason
    }
}

【问题讨论】:

  • 不详述,但您是否考虑过使用堆栈(在 LIFO 集合的意义上,而不是旧的 Stack)?

标签: java algorithm math recursion parentheses


【解决方案1】:

正如评论中所说,您可以考虑使用堆栈。当前字符为({[ 时,入栈。当前字符为)}] 时,检查栈中是否有对应字符(有效输入,必须存在)并弹出。

import java.util.Stack;

class Solution {

    public boolean validParen(String input) {

        if (input.isEmpty()) {
            return true;
        } else {
            Stack<Character> stack = new Stack<>();
            for (int i = 0; i < input.length(); i++) {
                char current = input.charAt(i);
                if (current == '(' || current == '[' || current == '{') {
                    stack.push(current);
                } else {
                    if(stack.isEmpty()) {
                          return false;
                    }
                    char peekChar = stack.peek();
                    if ((current == ')' && peekChar != '(')
                            || (current == '}' && peekChar != '{')
                            || (current == ']' && peekChar != '[')) {
                        return false;  // for a valid input, a close brackets must have an open brackets
                    } else {
                        stack.pop();
                    }
                }
            }
            return true; 
        }
    }


    public static void main(String[] args) {
        Solution sol = new Solution();
        System.out.println(sol.validParen(""));
        System.out.println(sol.validParen("()"));
        System.out.println(sol.validParen("()[]{}"));
        System.out.println(sol.validParen("(]"));
        System.out.println(sol.validParen("([)]"));
        System.out.println(sol.validParen("{[]}"));
    }

}

【讨论】:

  • 如果第15行的条件为假,可以立即返回假。否则,这是一个很好的解决方案。
  • 解决方案还可以,但是介绍句实在是让人迷惑。例如,在(((())))[[[]]] 中,第一个字符与length - 1 处的字符没有任何关系。
  • 我知道使用堆栈是一个更好的解决方案,但我的解决方案将适用于嵌套括号,因为它会检查最嵌套的对并将其删除并继续此过程,直到输入为空字符串。跨度>
  • @ken24ny 这也适用于嵌套括号。堆栈的功能不像集合,因此可能存在重复条目。访问的每一级嵌套括号都会将一个额外的开始符号推入堆栈。我刚刚对其进行了测试,它在((((())))) 之类的输入上运行良好。
  • @NengLiu 实际上,回到你原来的解决方案,那是无效的。如果没有您添加的return false,则在([}]) 等表达式上输入失败,因为它会跳过} 字符,最终堆栈将为空!
【解决方案2】:

你试过替换

validParen(input);

return validParen(input);

? 否则这条线并没有真正做太多;)

从调用顺序的角度来看,无论您是从 a() 还是从其他任何地方调用方法 a() 都没有关系。 我们来看一个简单的例子

public int getOne() {
   return 1;
}

public int getA(int a) {
   /*
   what you do here is call getOne(). The method will be called,
   and it will produce some result, but this result will not be persisted
   in any way, you will just go to the next line where the original a's
   value will be returned
    */
   getOne(); 
   return a;


}

这个案子是不是更清楚一点?显然,如果您调用getA(2),将返回2,而不是1,即使在内部调用getOne() - 它的结果也会被忽略。

【讨论】:

  • 难道validParen(input) 最终会到达基本情况并返回true?我不明白退货有什么不同?
  • 想想吧。您调用一个方法,忽略它的结果(无论它返回 true 还是 false,它都会被忽略,因为您不会在 return 语句中“传递”或将其分配给变量),然后直接传递给下一行返回 false;尝试在您的脑海中“调试”它并仔细考虑会发生什么。是的,也许会返回 true,但不是从您的原始方法返回,而是从内部调用的方法返回。这个结果不会以任何方式被考虑在内。这与调用 int a = 1; 基本相同一个+1; // 这里有一个加法,但是它的结果被忽略了。返回一个;
  • 让我编辑我的答案,因为 cmets 使用起来不太舒服
  • 很抱歉,我是初学者,很难理解这一点。你的意思是在 if 语句中我什么都没有返回,即使它递归地调用了一个最终到达 return 语句的方法?
  • 伙计,我不知道你的问题是什么,但这段代码确实有效。享受
【解决方案3】:

导入 java.util.Stack;

公共类 ValidBracesTest {

public static void main(String[] args) {

    System.out.println(isValid("( [ { } ] )".toCharArray())); // valid
    System.out.println(isValid("([{}])".toCharArray())); // valid
    System.out.println(isValid("([)]".toCharArray())); // invalid
    System.out.println(isValid("(}".toCharArray())); // invalid

}

public static boolean isValid(char[] charArray) {
    Stack<Character> container = new Stack<Character>();

    for (char c : charArray) {

        if (c == ' ') {
            continue;
        }

        if (c == '(' || c == '{' || c == '[') {
            container.push(c);
        } else if (c == ')' && container.peek() == '(' 
                || (c == '}' && container.peek() == '{')
                || (c == ']' && container.peek() == '[')) {
            container.pop();
        } else {
            return false;
        }

    }

    return container.isEmpty();
}

}

【讨论】:

    【解决方案4】:
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i =0; i < s.length(); i++){
           Character currentChar = s.charAt(i);
           if (currentChar == '(' || currentChar == '{' || currentChar == '[') {
                stack.push(currentChar);
           } else if(!stack.isEmpty()){
               if (currentChar == ')' && stack.peek() == '(' 
                || (currentChar == '}' && stack.peek() == '{')
                || (currentChar == ']' && stack.peek() == '[')) {
                    stack.pop();
                } else {
                    return false;
                }
           } else {
                return false;
            }
        }
    
        return stack.isEmpty();
    }
    

    【讨论】:

    • 请在回答问题时考虑解释您的代码。
    【解决方案5】:

    这应该是一个优雅的版本,您可以在其中推动括号的反面并检查完整性。

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

    【讨论】:

      猜你喜欢
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多