栈的常见题型

news2024/11/25 2:02:46

1.有效的括号

char pairs(char a)
{
    if(a=='}')return '{';
    if(a==']')return '[';
    if(a==')')return '(';
    return 0;
}
bool isValid(char* s) {
    char* stack=(char*)malloc(sizeof(char)*10000);
    int top=0;
    int len=strlen(s);
    if(len%2==1)return false;
    for(int i=0;s[i];i++)
    {
        char ch=pairs(s[i]);
        if(ch)
        {
            if(top==0||stack[top-1]!=ch)return false;  
            top--;
        }
        else 
        {
            stack[top++]=s[i];
        }
        
    }
    return top==0;
}

      这个题为什么能想到用栈来解决呢?因为括号匹配的问题本质上涉及到”最近匹配原则“,就是最后出现的左括号应该与最先出现的右括号匹配。栈是一种后进先出的数据结构,非常适合用于处理最近匹配的问题,当我们遍历每个字符时,遇到左括号就将其压入栈中,而在遇到右括号时,就从栈中弹出最近遇到的左括号并检查是否匹配·。如果匹配就继续遍历;如果不匹配,或者栈为空而无法弹出,则说明括号不匹配。

2.逆波兰表达式求值

int evalRPN(char ** tokens, int tokensSize){
    int stack[tokensSize];
    int top=0;
    for(int i=0;i<tokensSize;i++)
    {
        char* c=tokens[i];
        int n=strlen(c);
        if(n>1||isdigit(c[0]))
    {
        stack[top++]=atoi(c);
    }
    else
    {
        int num1=stack[--top];
        int num2=stack[--top];
        switch(c[0])
        {
            case '+':
               stack[top++]=num2+num1;
               break;
            case '-':
               stack[top++]=num2-num1;
               break;
            case '*':
                stack[top++]=num2*num1;
                break;
            case '/':
                stack[top++]=num2/num1;
                break;
        }
    }
    }
    return stack[top-1];
}

     什么是逆波兰表示法? 一个表达式E的后缀形式可以如下定义:(1)如果E是一个变量或常量,则E的后缀式是E本身。(2)如果E是E1 op E2形式的表达式,这里op是任何二元操作符,则E的后缀式为E1'E2' op,这里E1'和E2'分别为E1和E2的后缀式。(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:

ab+(a+b)*c-(a+b)/e的后缀表达式为:
(a+b)*c-(a+b)/e
→((a+b)*c)((a+b)/e)-
→((a+b)c*)((a+b)e/)-
→(ab+c*)(ab+e/)-
→ab+c*ab+e/-

 

      就是不断把中缀表达式的二元运算符放到后缀上,有括号的最后再放,因为括号运算优先级最高,那把逆波兰表达式转化为中缀表达式,就是逆过程,我们也可以看到,每遇到一个运算符,我们总是把与这个运算符距离最近的两个数拿来运算,也是最近匹配的问题,所以我们想到用栈来解决问题,首先定义一个栈,然后就遇到了一个问题,我们遍历tokens时,怎么判断是不是数字呢,只有数字我们才能入栈,有三种情况:一位数,多位数,负数,对于负数我们可以计算这个字符的长度,如果长度大于1,就是数字;对于一位数乃至多位数,我们可以使用isdigit函数进行判断,isdigit函数用于判断数字字符(0-9),参数为字符,如果不是返回0,是的话返回非0,如果返回非0,我们就把压入栈中,这里还用到了atoi函数,atoi函数用于把数字字符转化为数字,参数为字符串,这样我们就把数字压入栈中了,如果遇到了运算符,用switch语句判断是什么运算符,然后对最近的两个数字进行运算,把运算的结果压入栈中,直到遇到下一个运算符继续进行运算,最后返回栈顶的值即可。

3.反转链表

struct ListNode* reverseList(struct ListNode* head){
    if(head == NULL || head->next == NULL){
        return head;
    }
    int *stack = (int *)malloc(sizeof(int) * 5001);
    int top = 0;
    struct ListNode* now = head;
    while(now){
        stack[top++] = now->val;
        now = now->next;
    }
    struct ListNode* ret = malloc(sizeof(struct ListNode));
    struct ListNode* retHead = ret;
    while(top--){
        head->val = stack[top]; 
        ret->next = head;
        ret = ret->next;
        head = head->next;
    }
    return retHead->next;
}


     之前我们反转链表时是把next指针不断进行修改,而反转链表像不像先进后出的问题,我们同样可以使用栈数据结构来解决问题,首先判断链表是否为空或者是否只有一个结点,因为这种情况下我们不需要进行反转,直接返回head即可。

     接下来我们定义一个栈stack,和头指针now指向head,把链表各个结点的值存入栈中,接着我们再定义一个ret作为反转后的链表的虚拟头结点,以及返回的结点,接着就是栈中的元素出栈,将链表的值进行更新,ret和head不断向右走,最后返回retHead->next;

4.回文链表

bool isPalindrome(struct ListNode* head){
      int* stack=(int*)malloc(sizeof(int)*100000);
      int top=0;
      struct ListNode* cur=head;
      while(cur)
      {
          stack[top++]=cur->val;
          cur=cur->next;
      }
      while(top--)
      {
          if(stack[top]!=head->val)return false;
          head=head->next;
      }
      return true;
}

      这个题也很精彩,我们只需要值进行判断即可,回文就是前后对应相同,从后和从前看都是一样的链表就是回文链表,也就是说我们只需要判断末尾的值是否和开头的值是否相等即可,我们可以用栈来解决,毕竟栈是先进后出,末尾的值会先出栈。

     我们先定义一个栈,遍历链表,将值压入栈中,然后从栈顶开始遍历,如果遍历到的栈顶的值和从head开始遍历的值不相等,就不是回文链表,否则就是回文链表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1332965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BTF:实践指南

本文地址&#xff1a;BTF&#xff1a;实践指南 | 深入浅出 eBPF 1. BPF 的常见限制 1.1 调试限制1.2 可移植性2. BTF 是什么&#xff1f;3. BTF 快速入门 3.1 BPF 快速入门3.1 BTF 和 CO-RE4. 结论 BPF 是 Linux 内核中基于寄存器的虚拟机&#xff0c;可安全、高效和事件驱动…

【STM32】STM32学习笔记-TIM定时中断(13)

00. 目录 文章目录 00. 目录01. TIM简介02. 定时器类型03. 基本定时器04. 通用定时器05. 高级定时器06. 定时中断基本结构07. 预分频器时序08. 计数器时序09. 计数器无预装时序10. 计数器有预装时序11. RCC时钟树12. 附录 01. TIM简介 TIM&#xff08;Timer&#xff09;定时器…

数据库中间件介绍

文章目录 什么是数据库中间件&#xff1f;Smart-client 模式优点缺点 Proxy 模式优点缺点 单元化架构优点缺点 总结 数据库中间件是连接数据库和应用程序之间的软件层&#xff0c;用于简化数据库管理、提高性能和可伸缩性&#xff0c;同时提供额外的功能和服务。在分布式系统和…

mybatis的二级缓存使用以及禁用

目录 mybatis 二级缓存配置有两处 全局设置 mapper 设置 测试代码 执行结果 源码执行逻辑 创建 SqlSession 二级缓存配置是否添加 解析 cache 标签 XMLMapperBuilder MapperBuilderAssistant CacheBuilder PerpetualCache SerializedCache LoggingCache 将 cach…

Python教程(17)——python模块是什么?python模块详解

Python模块简介 模块是一个包含了Python定义和语句的文件&#xff0c;可用于将功能组织成可重用和可维护的代码块。每个Python文件都可以作为一个模块&#xff0c;模块可以包含变量、函数、类或可执行代码。通过使用模块&#xff0c;我们可以将代码分离成逻辑单元&#xff0c;…

【vtkWidgetRepresentation】第十八期 vtkHoverWidget

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享vtkHoverWidget,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. vtkHoverWidget vtkHoverWidget用于在呈现窗口中…

Python生成圣诞节贺卡-代码案例剖析【第18篇—python圣诞节系列】

文章目录 ❄️Python制作圣诞节贺卡&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析 ❄️Python制作圣诞树贺卡&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析&#x1f338;总结 &#x1f385;圣诞节快乐&#xff01; ❄️Python制作圣诞节贺卡 …

商户如何去申请支付宝小程序以及对接团购(天财商龙)

申请支付宝小程序的前提&#xff1a;必须要是支付宝实名认证用户&#xff08;要申请企业支付宝&#xff09; 1.申请企业支付宝 申请网址&#xff1a;支付宝商家后台 https://b.alipay.com 企业支付宝必须是法人扫码进行注册 申请资料&#xff1a;企业的营业执照&#xff0c;没…

simulink代码生成(二)——ADC采样模块

这一节梳理如何使用C2000库中的ADC模块&#xff0c;从而实现采样&#xff1b; 先预留几个问题&#xff0c;逐步进行解决。 &#xff08;1&#xff09;在simulink中C2000的ADC采样模块设置是怎么样的&#xff1f;各个选项卡代表什么&#xff1f; &#xff08;2&#xff09;AD…

【开源】基于JAVA语言的学校热点新闻推送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…

谷粒商城|仓储服务-仓库管理

配置服务中心 cloud:nacos:discovery:server-addr: 127.0.0.1:8848application:name: guliware在网关配置路由转发 guligateway .yml配置文件 - id: ware_routeuri: lb://guliwarepredicates:- Path/api/guliware/**filters:- RewritePath/api/(?<segment>.*),/$\{segm…

计算机网络复习-OSI TCP/IP 物理层

我膨胀了&#xff0c;挂我啊~ 作者简介&#xff1a; 每年都吐槽吉师网安奇怪的课程安排、全校正经学网络安全不超20人情景以及割韭菜企业合作的FW&#xff0c;今年是第一年。。 TCP/IP模型 先做两道题&#xff1a; TCP/IP协议模型由高层到低层分为哪几层&#xff1a; 这题…

EasyPoi(excel导入导出)

一&#xff0c;依赖包&#xff1a; <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.1.3</version></dependency> 二&#xff0c;官网文档 1. 前言 - Powered…

格密码基础:q-ary格

目录 一. 格密码的重要性 二. 格密码基础 2.1 格点的另一种理解方式 三. q-ary格 3.1 q-ary垂直格 3.2 q-ary格 3.3 二者结合 四. 论文中的q-ary格 4.1 定理1 4.2 定理2 4.3 定理3 一. 格密码的重要性 格密码的基础是研究格点上的困难问题&#xff0c;这种格点使用…

从浮点数度分秒1.40000中无损精度提取1度40分00.0秒的方法

那些最好的程序员不是为了得到更高的薪水或者得到公众的仰慕而编程&#xff0c;他们只是觉得这是一件有趣的事情&#xff01; 从浮点数度分秒1.40000中无损精度提取1度40分00.0秒的方法 &#x1f340;前言&#x1f338;传统的提取方法&#x1f516;算法介绍&#x1f9fe;Python…

Java研学-HTTP 协议

一 概述 1 概念和作用 概念&#xff1a;HTTP 是 HyperText Transfer Protocol (超文本传输协议)的简写&#xff0c;它是 TCP/IP 协议之上的一个应用层协议。简单理解就是 HTTP 协议底层是对 TCP/IP 协议的封装。   作用&#xff1a;用于规定浏览器和服务器之间数据传输的格式…

(企业 / 公司项目)如何使用分布式任务调度框架Quartz集成 和 SpringBoot自带的定时任务集成?

SpringBoot自带的定时任务 首先在你的微服务项目中创建一个新的模块&#xff0c;定时调度模块 pom.xml里面关联公共模块common的依赖其他不需要改变 然后启动类别删&#xff0c;启动项目是否报错&#xff0c;写一个简单的测试类访问路径是否成功 package com.jiawa.train.bat…

力扣日记12.24-【二叉树篇】236. 二叉树的最近公共祖先

力扣日记&#xff1a;【二叉树篇】236. 二叉树的最近公共祖先 日期&#xff1a;2023.12.24 参考&#xff1a;代码随想录、力扣 ps&#xff1a;提前祝 平安夜快乐&#xff01; 236. 二叉树的最近公共祖先 题目描述 难度&#xff1a;中等 给定一个二叉树, 找到该树中两个指定节点…

nodejs+vue+ElementUi摄影作品图片分享工作室管理系统

第1周 2.21&#xff5e;2.27 查阅资料&#xff0c;学习vscode开发平台和vue框架技术 第2周 2.28&#xff5e;3.6 对软件功能需求进行分析, 软件功能模块划分及软件界面设计 第3周 3.7&#xff5e;3.13 撰写并提交毕业设计开题报告、英文资料翻译 第4周 3.14&#xff5…

[Linux] MySQL数据库之索引

一、索引的相关知识 1.1 索引的简介 索引是一个排序列表&#xff0c;包含索引值和包含该值的数据行的物理地址&#xff08;类似于 c 语言链表&#xff0c;通过指针指向数据记录的内存地址&#xff09;。 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索…