投机取巧可不行,我们还是一步一步的解决吧

112 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情

题目描述

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。

初步思路

  • 这问题咋看挺难的,仔细一想感觉不是那么难,只需要满足括号的闭合即可。也就是说出现左括号那么下一个字符必然是有括号否则就是无效字符。按照这个思路我们实现下代码看看

for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (c=='(') {
        if (i < s.length() - 1) {
            if (s.charAt(i + 1)!=')') {
                return false;
            }
        }
    }
}
return true;

问题

image.png

  • 本以为就这样结束关灯睡觉了,谁承想是我把问题想的太简单了。

升级

  • 因为在测试算法的时候已经是半夜了,实在没心情搞什么性能问题了,我就直接点暴力破解了。既然你让我检测是否合法,那么我倒着来直接按照有效的字符进行删除,删除到最后如果是空字符的那么久说明你是有效的。

 public boolean isValid(String s) {
       while (s.contains("()") || s.contains("[]") || s.contains("{}")) {
           while (s.contains("()")) s = s.replace("()", "");
           while (s.contains("[]")) s = s.replace("[]", "");
           while (s.contains("{}")) s = s.replace("{}", "");
       }
       return s.isEmpty();
   }
  • 事实证明我的想法是可行的。那么我们就可以这样去检测。但是这只是一种投机的宣发,整整的我们还是需要按照算法的思维去破解他的。

算法

  • 做一个前置校验判断s参数是否为空,如果为空,我就默认返回true,否则我们进行下一步,创建一个stack 利用栈的特点先进后出,后进先出,遍历chart数组,我们就进行取反操作来判断以及利用stack 作为局部变量,for循环中没有匹配到就进行自我出栈,直到stack 为空说明满足了一下三个条件,视为题目所说的有效括号!

 public boolean isValid(String s) {
     if(s.isEmpty())
            return true;
        Stack<Character> stack = new Stack<Character>();
        //利用栈先进后出 stack 局部变量
        //当stack 压栈不成功后 后进去的括号自动弹出来 循环一次弹出一次
        //c!=stack.pop() 取反 相等就自动弹栈 一直弹到没有说明对上了
        for(char c:s.toCharArray()){
            if(c=='(')
                stack.push(')');
            else if(c=='{')
                stack.push('}');
            else if(c=='[')
                stack.push(']');
            else if(stack.empty()||c!=stack.pop())
                return false;
        }
        //循环完了 如果是空说明正确了 否则false
        if(stack.empty())
            return true;
        return false;
    }

总结

  • 怎么说呢,有些算法是可以投机破解的,但是想要提升自己的算法能力,还是需要一步一个脚印走下的