代码随想录算法训练营day11 20

栈的拿手好戏!| LeetCode:20. 有效的括号_哔哩哔哩_bilibili

栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项_哔哩哔哩_bilibili

栈的最后表演! | LeetCode:150. 逆波兰表达式求值_哔哩哔哩_bilibili

20. 有效的括号

思路:最先出现的右括号肯定是由最邻近的最括号进行抵消的,所以记录左括号的应该需要满足后进先出的格式。然后考虑这样几个边界问题:1、右括号为什么不要进栈?(因为右括号进栈无法再出栈,右括号只是起到提取栈内元素的作用) 2、出栈的括号与当前右括号不匹配怎么办,做哪些操作。(当前括号不匹配,则表明这个右括号无法匹配,而括号匹配是不可以越过括号的,所以直接返回false)

其实在最早使用c语言基于数组构建栈的时候,只需要一个尾部指针即可完成构建。所以对于解题减少时间开销,就可以基于所给出的数组,使用静态指针直接在当前数组上作为栈实现解题。给出两种解法)

// 时间复杂度都是O(n),空间复杂度为o(n),时间开销全在构建的额外的辅助Stack的pop、push操作上
class Solution {
    public boolean isValid(String s) {
        // 思路:最先出现的右括号肯定是由最邻近的最括号进行抵消的,所以记录左括号的应该需要满足后进先出的格式
        // 这样几个问题:1、右括号为什么不要进栈? 2、出栈的括号与当前右括号不匹配怎么办,做哪些操作

        // 构建栈进行求解
        // if(s.length() == 0 || s.length() == 1 || s.length()%2 != 0)
        //     return false;
        
        // Stack<Character> stack = new Stack<>();
        // for(int i=0; i<s.length(); i++){
        //     if(s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{'){
        //         stack.push(s.charAt(i));
        //     }
        //     else{
        //         if(s.charAt(i) == ')' && stack.isEmpty() == false && stack.peek() == '(')   stack.pop();
        //         else if(s.charAt(i) == ']' && stack.isEmpty() == false && stack.peek() == '[')  stack.pop();
        //         else if(s.charAt(i) == '}' && stack.isEmpty() == false && stack.peek() == '{')  stack.pop();
        //         else    return false;
        //     }
        // }
        // if(stack.isEmpty() == true)
        //     return true;
        // return false;

        // 解法二,就是利用给出的数组,结合定义静态栈指针实现计算,本质上就是快慢双指针,时间效率会得到大幅提升
        // 时间最快的还得是通过递归来实现,但需要结合题目来看是否可以使用递归,下面的150就可以
        if(s.length() == 0 || s.length() == 1 || s.length()%2 != 0)
            return false;

        char[] ch = s.toCharArray();
        Map<Character,Character> map = new HashMap<>();
        map.put(')','(');
        map.put(']','[');
        map.put('}','{');

        int j = -1;
        for(int i=0; i<ch.length; i++){
            // 出现右括号了
            if(map.containsKey(ch[i]) == true){
                if(j>=0 && map.get(ch[i]) == ch[j])
                    j--;
                else
                    return false;
            }
            else
                ch[++j] = ch[i];
        }
  

        if(j == -1)
            return true;
        return false;

    }
}

1047. 删除字符串中的所有相邻重复项

思路:相邻的元素抵消,是后进先出思想的使用;此外抵消之后,前部分元素可能与之后的元素继续抵消,也即持续出栈,因此使用栈来解题呼之欲出。另外使用静态指针的方式继续减少时间开销。并且不管在什么操作上,只要是涉及读取元素,首要考虑采用数组。

// 时间复杂度O(n),空间复杂度大于O(n),因为多构建了一个StringBuilder
class Solution {
    public String removeDuplicates(String s) {
        
        // 每一次删除两个,而且是删除的位置是相邻的元素,那么又是采用栈可以很好的解决,
        // 因为返回的结果是字符串,而栈无法直接将字符拼接成字符串进行返回,因此可构建数组实现栈的模拟,而这里的数组可使用StringBuilder来模拟,
        // StringBuilder比StringBuffer速度快很多

        StringBuilder builder = new StringBuilder();
        char[] ch = s.toCharArray();
        int j = -1;
        for(int i=0; i<ch.length; i++){
            if(j >= 0 && ch[i] == ch[j])
                j--;
            else
                ch[++j] = ch[i];
        }

        for(int i=0; i<=j; i++)
            builder.append(ch[i]);
        return builder.toString();

        // 但是使用数组进行数据的读取与比较比基于StringBuilder的读取来的快的多,所以只需要采用StringBuilder作为结果返回的容器即可
        // StringBuilder builder = new StringBuilder();
        // int j = -1;
        // for(int i=0; i<s.length(); i++){
        //     if(j >= 0 && s.charAt(i) == builder.charAt(j))
        //         builder.deleteCharAt(j--);
        //     else
        //         builder.insert(++j, s.charAt(i));


**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/a410ca6ed6efe55ccf6c49179b2ca9c7.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/5687f34b7b4612b1ff816eebfbd9bbc0.png)
![img](https://img-blog.csdnimg.cn/img_convert/9bfabec9593be66d074d3b293886d6a2.png)
![img](https://img-blog.csdnimg.cn/img_convert/9d1deaba1270584144280356a31db66a.png)
![img](https://img-blog.csdnimg.cn/img_convert/eae5994c1ce07bd84eba3ca33a647646.png)
![img](https://img-blog.csdnimg.cn/img_convert/4395aa28595bf024f2ed5bc6af9a0f10.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)**
![img](https://img-blog.csdnimg.cn/img_convert/ca1073e317ffe32055a744f6e31207bf.png)



## 算法

1. 冒泡排序

2. 选择排序

3. 快速排序

4. 二叉树查找: 最大值、最小值、固定值

5. 二叉树遍历

6. 二叉树的最大深度

7. 给予链表中的任一节点,把它删除掉

8. 链表倒叙

9. 如何判断一个单链表有环

   ![](https://img-blog.csdnimg.cn/img_convert/1fae61e15e1e82961a1a92b7a0310898.webp?x-oss-process=image/format,png)

>由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!



**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
![img](https://img-blog.csdnimg.cn/img_convert/05efbb682eb8f98c725618d66244960d.png)

绍,每个小节点里面都有更细化的内容!



**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-73RIA95B-1712899383018)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值