每日一算法(有效的括号)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

  • 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
    • 有效字符串需满足:左括号必须用相同类型的右括号闭合。
    • 左括号必须以正确的顺序闭合。
    • 每个右括号都有一个对应的相同类型的左括号。

提示:以下是本篇文章正文内容,下面案例可供参考

一、Stack解决

  • 思路:判断当前字符串的长度是不是偶数,然后再讲括号存放到哈希中,在进行循环,使用栈来检查括号的匹配关系。当遇到左括号时,将其压入栈中;当遇到右括号时,弹出栈顶元素并检查是否匹配
    public boolean isValid(String s) {
        // 如果字符串的长度是奇数,那么他不可能是有效的括号
        if (s.length() % 2 != 0) {
            return false;
        }
        //用哈希存放对应的关系
        Map<Character, Character> map = new HashMap<>();
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');
        //用栈来存储遍历过程中的括号
        Stack<Character> stack = new Stack<>();
        //遍历输入的字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 如果当前字符是右括号
            if (map.containsKey(c)) {
                // 弹出栈顶元素,如果栈为空,用 '#' 表示
                char teop = stack.isEmpty() ? '#' : stack.pop();

                if (map.get(c) != teop) {
                    return false;
                }
            } else {
                // 如果当前字符是左括号,存放到栈 中
                stack.push(c);
            }
        }
        // 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
        return stack.isEmpty();
    }

二、isValidArray数组模拟栈

  • 思路:使用字符数组模拟栈,然后再使用哈希存放括号的对应关系,再进行循环,使用数组模拟栈来检查括号的匹配关系。当遇到左括号时,将其压入数组模拟栈中;当遇到右括号时,弹出栈顶元素并检查是否匹配,最终,如果栈为空,表示所有括号都匹配成功

解法一

   public static boolean isValidArray(String s) {
        if (s.length() % 2 != 0) {
            return false;
        }

        // 使用字符数组模拟栈
        char[] stack = new char[s.length()];
        int index = 0;

        // 使用 HashMap 存储括号的对应关系
        Map<Character, Character> map = new HashMap<>();
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');

        // 遍历输入的字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (map.containsKey(c)) {
                // 如果是右括号,检查栈顶元素是否匹配
                char top = (index == 0) ? '#' : stack[--index];

                if (map.get(c) != top) {
                    return false;
                }
            } else {
                // 如果是左括号,将其推入栈
                stack[index++] = c;
            }
        }

        // 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
        return index == 0;
    }

解法二

 public static boolean isValidChar(String s) {
        //判断是不是奇数
        if (s.length() % 2 != 0) {
            return false;
        }
        // 使用字符数组模拟栈
        char[] stack = new char[s.length()];
        int top = 0;

        // 遍历输入的字符串
        for (char c : s.toCharArray()) {
            if (c == ')' && top > 0 && stack[top - 1] == '(' ||
                    c == ']' && top > 0 && stack[top - 1] == '[' ||
                    c == '}' && top > 0 && stack[top - 1] == '{') {
                // 如果当前字符是右括号且栈非空且栈顶元素与之匹配,则出栈
                top--;
            } else {
                // 否则,将当前字符压入栈
                stack[top++] = c;
            }
        }
        // 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
        return top == 0;
    }

二、双端队列

  • 思路:
    • 检查输入字符串的长度是否为偶数,因为有效的括号匹配必须是成对的,如果长度为奇数,直接返回false
    • 创建一个双端队列(Deque)来模拟栈的行为。在Java中,LinkedList实现了Deque接口,因此可以用它来实现栈
    • 使用HashMap存储括号的对应关系,其中键是右括号,值是对应的左括号。这样可以方便地查找匹配关系
    • 遍历输入字符串的每个字符
    • 检查栈是否为空。如果为空,表示所有括号都成功匹配,返回true;否则,返回false
   public static boolean isValidDeque(String s) {
        if (s.length() % 2 != 0) {
            return false;
        }

        // 使用双端队列模拟栈
        Deque<Character> stack = new LinkedList<>();

        // 使用 HashMap 存储括号的对应关系
        Map<Character, Character> map = new HashMap<>();
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');

        // 遍历输入的字符串
        for (char c : s.toCharArray()) {
            if (map.containsKey(c)) {
                // 如果是右括号,检查栈顶元素是否匹配
                char top = stack.isEmpty() ? '#' : stack.poll();

                if (map.get(c) != top) {
                    return false;
                }
            } else {
                // 如果是左括号,将其推入栈
                stack.push(c);
            }
        }

        // 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
        return stack.isEmpty();
    }
  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值