前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用自定义链式栈解决力扣括号匹配问题

用自定义链式栈解决力扣括号匹配问题

作者头像
智慧zhuhuix
发布2020-08-14 16:21:59
5530
发布2020-08-14 16:21:59
举报

一、背景

在力扣题库中有一道经典的栈表应用问题:有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 有效字符串需满足: 1、 左括号必须用相同类型的右括号闭合。 2、左括号必须以正确的顺序闭合。 3、注意空字符串可被认为是有效字符串。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/valid-parentheses

示例1

示例 2

示例 3

示例 4

示例 5

输入: "()"

输入: "()[]{}"

输入: "(]"

输入: "([)]"

输入: "{[]}"

输出: true

输出: true

输出: false

输出: false

输出: true

二、解题思路
在这里插入图片描述
在这里插入图片描述
  1. 栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,遍历完所有括号后 stack仍然为空,则认为字符串中的括号都完全匹配;
  2. 如果输入的字符串中有括号外的其它字符,则直接返回无效;
  3. 如果输入了空字符串,则不会产生入栈,栈仍然为空,也可返回有效。
三、编码实现

由于输入的字符串长度不定,并考虑自定义一个链式栈(无栈满问题,空间可扩充)进行编码实现。

1、结点

每个元素,除了存储其本身的信息(数据域)之外,还需存储一个指示其直接后继存放位置的指针。这两部分信息组成数据元素的存储映像,称为结点(Node)。

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
/**
 * 结点类
 *
 * @author zhuhuix
 * @date 2020-05-29
 */
public class Node<T> {
    // 数据域
    private T data;
    // 指针
    private Node<T> next;

    Node(T t, Node<T> n) {
        this.data = t;
        this.next = n;
    }

    public T getData() {
        return data;
    }

    public Node<T> getNext() {
        return next;
    }

    public void setNext(Node<T> next) {
        this.next = next;
    }
}
2、链式栈
  • 链式栈是由N个结点组成的;
  • 入栈出栈都在栈顶完成;
  • 从栈顶以下的结点的指针链接下一个结点,直至栈尾。
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
/**
 * 链栈的实现
 *
 * @author zhuhuix
 * @date 2020-05-29
 */
public class LinkStack<T> {
    // 栈顶元素
    private Node<T> top;
    // 栈的长度
    private Integer length;

    // 构造方法
    public LinkStack() {
        this.top = null;
        this.length = 0;
    }

    // 入栈push
    public void push(T t) {
        this.top = new Node<>(t, this.top);
        this.length++;
    }

    // 出栈pop
    public T pop() {
        if (this.top == null) {
            return null;
        }
        T data = this.top.getData();
        this.top = this.top.getNext();
        this.length--;
        return data;
    }

    // 查看栈顶元素
    public T peek() {
        if (this.top == null) {
            return null;
        }
        T data = this.top.getData();
        return data;
    }

    // 栈是否为空
    public boolean isEmpty(){
        return this.length==0;
    }

    // 销毁栈
    public void destroy() {
        this.top =null;
        this.length = 0;
    }


    public Integer getLength() {
        return this.length;
    }
}
3、用链式栈实现括号匹配的判断
代码语言:javascript
复制
/**
 * ==用链式栈解决力扣括号匹配问题==
 * <p>
 * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
 * 有效字符串需满足:
 * 左括号必须用相同类型的右括号闭合。
 * 左括号必须以正确的顺序闭合。
 * 注意空字符串可被认为是有效字符串。
 * <p>
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode-cn.com/problems/valid-parentheses
 *
 * @author zhuhuix
 * @date 2020-05-30
 */
public class LinkStackTest {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入只包括 '(',')','{','}','[',']' 的字符串");
        String s = bufferedReader.readLine();
        if (isValid(s)) {
            System.out.println("字符串的括号相互匹配,有效");
        } else {
            System.out.println("字符串的括号不匹配,无效");
        }
    }

    /**
     * 通过左括号入栈,右括号出栈的算法判断括号是否匹配
     *
     * @param s 待判断的字符串
     * @return 不匹配返回false, 匹配返回true
     */
    public static boolean isValid(String s) {
        LinkStack<String> stack = new LinkStack<>();
        for (int i = 0; i < s.length(); i++) {
            String ch = s.substring(i, i + 1);
            switch (ch) {
                // 左括号入栈
                case "(":
                case "[":
                case "{":
                    stack.push(ch);
                    break;
                case ")":
                    if (stack.isEmpty()) {
                        return false;
                    }
                    // 如果栈顶为左小括号,则匹配出栈
                    if ("(".equals(stack.peek())) {
                        stack.pop();
                    } else {
                        return false;
                    }
                    break;
                case "]":
                    if (stack.isEmpty()) {
                        return false;
                    }
                    // 如果栈顶为左中括号,则匹配出栈
                    if ("[".equals(stack.peek())) {
                        stack.pop();
                    } else {
                        return false;
                    }
                    break;
                case "}":
                    if (stack.isEmpty()) {
                        return false;
                    }
                    // 如果栈顶为左大括号,则匹配出栈
                    if ("{".equals(stack.peek())) {
                        stack.pop();
                    } else {
                        return false;
                    }
                    break;
                default:
                    return false;

            }
        }
        return stack.isEmpty();
    }
}
四、代码执行
测试1
在这里插入图片描述
在这里插入图片描述
测试2
在这里插入图片描述
在这里插入图片描述
测试3
在这里插入图片描述
在这里插入图片描述
空字符串测试
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景
    • 二、解题思路
      • 三、编码实现
        • 四、代码执行
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档