FTPrep, 20 Valid Parentheses

最直接的想法,存一个map,把左括号和右括号,作为key/value这两类的char储存进去。然后遍历string的时候,check是左括号( map.keySet().contains(ch)) 那就push进stack,如果不是key的话,检查两个条件,1 stack如果为空 return false,2如果不为空,这个时候肯定要pop出来,所以不要用peek了,直接pop,如果不是 key to value的 match,那么就return false

代码:

public class Solution {
    public boolean isValid(String s) {
        int len=s.length();
        if(len==0) return false;
        Map<Character, Character> map = new HashMap<Character, Character>();
        map.put('(',')');
        map.put('{','}');
        map.put('[',']');
        Stack<Character> stack = new Stack<Character>();
        for(char c : s.toCharArray()){
            if(map.keySet().contains(c)) stack.push(c);
            else{
                if(stack.isEmpty() || (c!=map.get(stack.pop()))) return false;
            }
        }
        return stack.isEmpty();
    }
}

参考了一个不用map的方法,有两点值得分析:

1,只能把所以各种左括号挨个罗列出来,只有3个的时候还适用

2,把key to value match 键值对应情况,在push进stack的时候就表现出来,直接存入相对应的右括号,这其实相当于上面代码中push进去是 map.get(ch), 所以在遇到右括号时就不用再去使用get()方法了,这两种选择再有map的时候都一样,但是当没有map的时候,还是后者更加省事,省去再去挨个罗列情况的过程。

!但是,从更加generalize的角度来说,用map来记录左右对应关系更加适用,如果有K=100种左括号右括号的对应关系,挨个罗列情况就变得非常不切实际。

代码如下:

public class Solution {
    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{    // 包括了右括号的三种情况,然后再在里面判断,而且写得极为简练,省略了很多redundant的东西
                if(stack.isEmpty() || c!=stack.pop()) return false;   // empty就return,如果没有empty,那么就直接pop进行对比,而不是peek()检查后,如果相等在pop,直接合并成一步,这是熟练之后的写法,何不是面试时的重点,不要求扣这么细 优化到这么细,写清楚更好
            }
        }
        return stack.isEmpty(); 
    }
}

过了几天我又看到这题,又写了一遍,尝试这不用map记录,直接罗列3种情况,看来之前写的总结还是会忘的,忘了之后居然退化到了最直白的代码,哈哈汗啊

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

//注意:在stack.peek()之前要check stack是否为空,使用isEmpty() 不是 empty().
卧槽,简直太navie了,上面有那么明显的重复代码 !stack.isEmpty() 居然不知道优化,唉真是naive,真是被动学习记忆,而不是有一个主动优化的意识,缺少了年轻时的那种表现的欲望,不会抓住甚至去挖掘表现自己的机会了。。

总结来说,简单一句话,用stack记录,如果左括号就压入,如果右括号,1,是空stack return false,2,非空,但是pop出来的不能match 也return false。最后检查stack是否为空。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值