leetcode - 20.有效的括号(LinkedHashMap)

leetcode题目有效的括号,分类是easy,但是博主前前后后提交了几十次才通过,现在记录一下使用Java语言的写法。
在这里插入图片描述

题目链接: 20.有效的括号

题目描述:

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
3.每个右括号都有一个对应的相同类型的左括号。

题目示例:

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

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

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

题目提示:

1. <= s.length <= 104
2. 仅由括号 '()[]{}' 组成

题目解读:

每个左括号都要有成对的右括号,成对的含义是
(1)属于"()"、"[]"、"{}"中的任意一对
(2)中间不存在其他字符,比如"()"
(3)中间存在其他成对的字符,比如"({[]})"

示例图:
在这里插入图片描述

一、 递归

基于以上的理解,博主最初选择使用递归消除字符的做法。只要左右相邻的字符成对就将其消除,递归至LinkedHashMap的长度为0或不再出现可消除的字符。

思路:
(1)使用LinkedHashMap保存入参用例中的所有字符。
(2)遍历LinkedHashMap,在存在相邻两个元素符合成对匹配条件时,将这两个元素记录下来,在一次遍历结束后从LinkedHashMap中移除。
(3)当LinkedHashMap长度为0,或者在一次遍历中没有产生新的待删除的元素,则跳出循环。
(4)当最终LinkedHashMap长度为0时,说明全部匹配成功。
class Solution {
    public boolean isValid(String s) {

        boolean res = false;
        char[] charArray = s.toCharArray();
        if (charArray.length % 2==1) {
            return res;
        }
        HashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
        for (int i =0; i < charArray.length; i++) {
            linkedHashMap.put(i, String.valueOf(charArray[i]));
        }

        List<String> leftList = Arrays.asList("(", "[", "{");
        List<String> rightList = Arrays.asList(")", "]", "}");

        // 当map中全部消除完,或上一轮没有可消除的值时跳出循环
        int lastIndex = 0;
        List<Integer> removeKeys = new ArrayList<>();
        while (!linkedHashMap.isEmpty()) {
            removeKeys = new ArrayList<>();
            for (Integer key : linkedHashMap.keySet()) {

                int pos = new ArrayList<Integer>(linkedHashMap.keySet()).indexOf(key);

                // 从第二个开始跟前面的比较,前面取最新的linkedMap的第一个,不是key=0
                if (pos > 0) {
                    if (leftList.contains(linkedHashMap.get(lastIndex))
                            && rightList.contains(linkedHashMap.get(key))
                            && (leftList.indexOf(linkedHashMap.get(lastIndex)) == rightList.indexOf(linkedHashMap.get(key)))) {
                        // 删除对应位置
                        removeKeys.add(lastIndex);
                        removeKeys.add(key);
                        linkedHashMap.put(lastIndex, "0");
                        linkedHashMap.put(key, "0");
                    }
                }
                // 保存上一个key的值
                lastIndex = key;
            }

            if (!removeKeys.isEmpty()) {
                removeKeys.forEach(linkedHashMap::remove);
            } else {
                break;
            }
        }


        if (linkedHashMap.isEmpty()) {
            res = true;
        }


        return res;
    }

}

该做法可以计算正确,但在遇到以下测试用例时,惨遭Time Limit Exceeded 👇。

String s = "[([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([([()])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])])]";

该测试用例长度为7000,以递归消除元素的方法需要递归遍历几千次,速度非常的慢。那么,提高速度最好的办法就是减少遍历次数。

二、栈

在评论区看了一圈,发现大佬们的基本都是用栈来解决。
但是博主平时基本不使用栈这种数据结构,对栈的了解仅停留在以下层面。

栈(Stack)是一种常见的数据结构,具有后进先出(LIFO,Last In First Out)的特性,即最后入栈的元素最先出栈。

所以依然选择使用熟悉的LinkedHashMap去实现LIFO这一行为。在加入LinkedHashMap前先判断是否与末尾的元素匹配,再决定后续的操作。仅需要遍历一次就可以完成所有的匹配判断。

思路:
(1)遍历入参的字符数组。
(2)如果linkedMap长度为空,当前字符直接加入,作为第一个字符。
(3)如果linkedMap长度不为空,取末尾元素与当前元素进行匹配。匹配成功,将末尾元素消除(弹出);匹配失败,将当前元素加入linkedMap(压入)
(4)字符数组遍历结束后,如果linkedMap为空,说明全部匹配。
class Solution {
    public boolean isValid(String s) {

        boolean res = false;
        char[] charArray = s.toCharArray();
        if (charArray.length % 2==1) {
            return res;
        }

        List<String> leftList = Arrays.asList("(", "[", "{");
        List<String> rightList = Arrays.asList(")", "]", "}");

        // 栈:一个一个往堆栈里填入,如果跟前一个匹配就双双丢出
        HashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
        for (int i =0; i < charArray.length; i++) {
            String s1 = String.valueOf(charArray[i]);
            // 当前linkedMap中的排列的第一位
            if (i== 0 || linkedHashMap.isEmpty()) {
                if (rightList.contains(s1)) {
                    return false;
                }
                linkedHashMap.put(i, String.valueOf(charArray[i]));
            } else {

                int lastPos = new ArrayList<Integer>(linkedHashMap.keySet()).get(linkedHashMap.size()-1);
                // 判断跟linkedMap中最新一位元素是否匹配
                String lastS1 = linkedHashMap.get(lastPos);
                if (leftList.contains(lastS1)
                        && rightList.contains(s1)
                        && (leftList.indexOf(lastS1) == rightList.indexOf(s1))) {
                    // 匹配成功,不加入linkedMap,并且将前一个元素从map中移除(弹出)
                    linkedHashMap.remove(lastPos);

                } else {
                    // 不匹配,将该元素加入linkedMap中(压入)
                    linkedHashMap.put(i, String.valueOf(charArray[i]));
                }
            }
        }
        // 全部消除完毕才是通过
        if (linkedHashMap.isEmpty()) {
            res = true;
        }
        return res;
    }
}

不过在使用LinkedHashMap时也碰到了一些问题,因为元素可以随意移除,所以key的排序不是连续的12345等。需要将key转为ArrayList,再通过ArrayList.get()方法获取最新一位元素key。

posted @ 2024-05-29 16:03  御坂10027  阅读(2)  评论(0)    收藏  举报  来源