给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串 s ,判断字符串是否有效。
    有效字符串需满足:

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

    示例 1:
    输入:s = “()”
    输出:true

    示例 2:
    输入:s = “()[]{}”
    输出:true

    示例 3:
    输入:s = “(]”
    输出:false

    示例 4:
    输入:s = “([)]”
    输出:false

    示例 5:
    输入:s = “{[]}”
    输出:true

    image.png

    遍历给定的字符串 ,当遇到一个左括号时,会期望在后续的遍历中,有一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此可以将这个左括号放入栈顶。
    当遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串无效。
    为了快速判断括号的类型,可以使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号。

    1. public boolean isValid(String s) {
    2. Map<Character, Character> map = new HashMap<>();
    3. map.put(')', '(');
    4. map.put('}', '{');
    5. map.put(']', '[');
    6. Stack<Character> stack = new Stack<>();
    7. for (int i = 0; i < s.length(); i++) {
    8. char c = s.charAt(i);
    9. // 若遇到右括号 弹出栈顶元素,进行比较,反之入栈
    10. if (map.containsKey(c)) {
    11. char topElement = stack.empty() ? '#' : stack.pop();
    12. // 若栈顶元素和右括号对应的左括号类型不匹配,则不是有效括号字符串
    13. if (topElement != map.get(c)) {
    14. return false;
    15. }
    16. } else {
    17. stack.push(c);
    18. }
    19. }
    20. return stack.isEmpty();
    21. }

    优化一下:可以提前判断一下字符串长度,如果是奇数,那么必定不是有效括号字符串

    1. public boolean isValid(String s) {
    2. // 奇数长度必定不是有效括号字符串
    3. if (s.length() % 2 == 1) {
    4. return false;
    5. }
    6. Map<Character, Character> map = new HashMap<>();
    7. map.put(')', '(');
    8. map.put('}', '{');
    9. map.put(']', '[');
    10. Stack<Character> stack = new Stack<>();
    11. for (int i = 0; i < s.length(); i++) {
    12. char c = s.charAt(i);
    13. // 若遇到右括号 弹出栈顶元素,进行比较,反之入栈
    14. if (map.containsKey(c)) {
    15. char topElement = stack.empty() ? '#' : stack.pop();
    16. // 若栈顶元素和右括号对应的左括号类型不匹配,则不是有效括号字符串
    17. if (topElement != map.get(c)) {
    18. return false;
    19. }
    20. } else {
    21. stack.push(c);
    22. }
    23. }
    24. return stack.isEmpty();
    25. }