合法的括号串

【问题描述】

一个合法的括号串,是指只包含括号的串,如果满足如下条件:

(1)<> () [] {} 这四对括号是合法的;

(2)如果r是合法括号串,则<r> (r) [r] {r}也是;

(3)如果r,s是合法括号串,则rs也是;

所以<<>> , [<>{}(())],[({<>})]是合法的括号串,而)(,[( ])就不是。

【输入形式】

输入第一行正整数t (10 ≤ n ≤ 100),表示有多少组测试数据。

后面有t行,每行一个只包含8种括号符号的括号串。

40%的括号串的长度L 2 ≤ L≤ 20;

30%的括号串的长度L 2 ≤ L≤ 200;

20%的括号串的长度L 2 ≤ L≤ 2000;

10%的括号串的长度L 2 ≤ L≤ 20000;

【输出形式】

对于每组测试数据,如果括号串是合法的,输出“Yes”(输出没有引号)占一行,否则,输出“No”(输出没有引号)占一行。

【样例输入】

6
<<>> 
)(
[<>{}(())]
[({<>})]
[(])
<([{

【样例输出】

Yes
No
Yes
Yes
No
No

解题思路

数据结构:栈

基本思路:遍历括号串,当遇到左括号时将其压入栈,遇到右括号时尝试从栈中弹出一个元素,并检查弹出的括号是否与当前的右括号匹配。如果在任何时候遇到不匹配的情况,或者在遍历完整个括号串后栈不为空,则该括号串不是合法的。

解题步骤:

  1. 初始化栈:用来存放遇到的左括号

  2. 遍历括号串:对每个字符进行检

    1. 如果是左括号,将其压入栈

    2. 如果是右括号,检查栈是否为空,若为空,则直接判定为非法。若不为空,则弹出栈顶元素,检查是否与当前右括号匹配

  3. 匹配检查:可以通过一个辅助的方法或者映射来实现

  4. 最终检查:遍历完毕后,检查栈是否为空。如果为空,合法;否则,不合法

Java代码

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        scanner.nextLine(); // 跳过行尾的换行符

        while(t-- > 0){ // t--错误
            String s = scanner.nextLine();
            System.out.println(isValid(s) ? "Yes" : "No");
        }

        scanner.close();
    }

    private static boolean isValid(String s) {

        // 初始化括号匹配关系
        Map<Character, Character> mappings = new HashMap<>();
        mappings.put('>','<'); //右括号作为键,左括号作为值,如果将右括号作为键,1. 使用HashMap的get方法来快速查找对应的左括号;2. 在遍历字符串时,检查当前字符是否为HashMap中的一个键来判断是否是右括号;3. 判断栈是否为空
        mappings.put(')','(');
        mappings.put(']','[');
        mappings.put('}','{');

        //判断方式
        Stack<Character> stack = new Stack<>();

        for (char c : s.toCharArray()) { //.toCharArray()字符串转换为字符数组
            // 如果是右括号
            if(mappings.containsKey(c)){ //.containsKey(c)
                char topElem = stack.isEmpty() ? '#' : stack.pop(); // 弹出栈顶元素进行匹配,如果栈为空,用一个不可能匹配的值代替
                if(topElem != mappings.get(c)) return false;
            }
            else stack.push(c); // 如果是左括号,压入栈中
        }
        return stack.isEmpty(); // 如果栈为空,说明括号完全匹配
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值