当前位置: 首页 > news >正文

网站建设哪家g好易企秀h5制作官网

网站建设哪家g好,易企秀h5制作官网,手机购物网站 设计,网站建设 教学视频教程文章目录一、栈1. 模拟实现栈2. 小试牛刀1. 判断一个栈的出栈顺序是否为题目给定情况2. 括号匹配3. 逆波兰表达式求值4. 求最小栈元素3. 单链表实现栈一、栈 栈说白了就是一个盒子,你先放进去的东西后拿出来,实现栈除了可以使用栈的类Stack外&#xff0…

1750074242584


文章目录

    • 一、栈
      • 1. 模拟实现栈
      • 2. 小试牛刀
        • 1. 判断一个栈的出栈顺序是否为题目给定情况
        • 2. 括号匹配
        • 3. 逆波兰表达式求值
        • 4. 求最小栈元素
      • 3. 单链表实现栈


一、栈

栈说白了就是一个盒子,你先放进去的东西后拿出来,实现栈除了可以使用栈的类Stack外,还可以使用链表
遵循先进先出,后进后出原则进行内容变化,重点是可以把递归转换成栈
我们查看其源码我们看到,它实质上是一个顺序表即数组,有压栈和出栈操作

1. 模拟实现栈

这次我们就不定义接口了,就直接写MyStack类吧,然后实现一些方法
我们重点就来讲压栈和出栈,压栈说白了就是先检测你的数组有没有满,满了就扩容,否则我们就直接让有效元素个数对应的下标的数字等于我们压入的数字(因为数组下标和实际位置差1的特性)
出栈就是先判断数字是不是空的,如果不是我们直接让有效数字个数减少,这样我们再次压入其他数字的时候就可以把原有数字覆盖
其他方法操作下来,我们的时间复杂度都是O(1)

//MyStack类
public class MyStack {public int [] elem;public int usedSize;public MyStack() {this.elem = new int[2];}public void push(int val) {if (isFull()) {this.elem = Arrays.copyOf(elem, 2 * elem.length);}elem[usedSize] = val;usedSize++;}public boolean isFull() {return usedSize == elem.length;}public int pop(){if(isEmpty()){throw new IsEmptyException("空数组异常");}int ret = peek();usedSize --;return ret;}public boolean isEmpty(){return usedSize == 0;}public int peek(){if(isEmpty()){throw new IsEmptyException("空数组异常");}return elem[usedSize-1];}public int size(){if(isEmpty()){throw new IsEmptyException("空数组异常");}return usedSize;}@Overridepublic String toString() {return "MyStack{" +"elem=" + Arrays.toString(elem) +", usedSize=" + usedSize +'}';}
}//测试类
public static void main(String[] args) {MyStack myStack = new MyStack();System.out.println("压栈");myStack.push(10);myStack.push(12);myStack.push(15);System.out.println(myStack);System.out.println("查看栈顶元素:"+myStack.peek());System.out.print("出栈:");System.out.print(myStack.pop()+" ");System.out.print(myStack.pop()+" ");System.out.print(myStack.pop());System.out.println();System.out.println("栈顺序"+myStack);Stack<Integer> stack = new Stack<>();}

打印结果就是这样,看起来一切正常
image-20250724154902039

2. 小试牛刀

1. 判断一个栈的出栈顺序是否为题目给定情况

题目链接
我们首先来讲讲这道题的核心思想是什么,根据题目要求
我们让i下标等于pushV,j下标等于popV
我们就以:pushV:1 2 3 4 5 和popV:4 3 5 1 2来讲解
我们先定义一个栈,叫stack,把右侧看做栈顶
好,我们定义好了i下标和j下标,此时它们分别代表数字1和数字4
我们比较i下标的数字和j下标数字是否匹配,发现不匹配,将i下标当前指向的元素放入栈中,此时我们得栈数字有[1],此时我们得i下标++,发现还是和j下标数字不匹配,继续放元素到栈中,继续++
直到[1,2,3,4],发现栈中的栈顶元素为4,和j下标元素匹配,那好,我们就弹出栈顶元素4,此时栈中元素为[1,2,3],此时j下标++向后走,走到数字3位置,此时我们再判断,栈中元素是空的吗,不是,我们还要继续判断相等,此时我们我们发现栈顶元素3和j下标当前的数字3匹配,我们栈顶元素继续弹出,k++一下向后走,走到数字5的位置,此时栈中元素为[1,2]
此时再判断,栈中元素是空的吗,不是,那我们还要继续判断相等,此时这一轮循环走完了,我们的i要++一下,走到数字5的位置,此时栈顶元素是2,和当前j下标的数字不一样,那我们是不是继续要从pushV中放数字,好,我们放入数字5,此时栈中元素为[1,2,5],栈顶元素和此时j下标的元素相等,我们此时弹出栈顶元素,此时j++向后走一位,走到1的位置,此时栈中元素为[1,2],此时栈顶元素和j下标并不匹配,这一轮循环走完,i++了一下,此时i就超过了原来的数组范围,大的循环走了出来,此时我们判断栈中是否还存有元素,发现还是有元素,那我们就可以知道“4 3 5 1 2”这个出栈顺序就不是原有合理顺序
如果出栈顺序是这样popV:4 5 3 2 1 ,一样的逐一的进行判断,发现最后栈是空的,那它就是和题目要求成立
但是有个特殊情况,比如这样:如果每个都匹配的情况 5 4 3 2 1 和 1 2 3 4 5
那内部进行判断的时候我们就要加上限制条件栈不可以为空并且j位置不能超过原数组范围,因为此时下标出了数组范围再取元素就空数组异常了,i不用判断是因为i有循环进行范围约束而j却没有

public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param pushV int整型一维数组 * @param popV int整型一维数组 * @return bool布尔型*/public boolean IsPopOrder (int[] pushV, int[] popV) {Stack <Integer> stack = new Stack<>();int i = 0;int j = 0;for(i = 0;i<pushV.length;i++){//大循环stack.push(pushV[i]);//还要考虑如果每个都匹配的情况 5 4 3 2 1 和 1 2 3 4 5while(!stack.empty() && j<= popV.length && stack.peek() == popV[j]){//内部循环stack.pop();j++;}}//看看stack空不空就行了return stack.empty();}
}
2. 括号匹配

题目链接
这个题目核心问题就是如何去直到括号在哪以及括号的个数的问题
我们就拿( [ ] )举例,我们定义一个栈,把左括号存到里面去,栈中元素和右括号进行匹配,如果相等则弹出栈顶元素,以此类推,如果在弹出过程中第一次遇到不匹配的情况,不要犹豫直接返回false,肯定不是匹配了的
我们再拿(( )情况举例,如果右括号你都匹配完了左括号还有剩余,那也是不匹配
还有( ))情况,左括号遍历完了右括号还有剩余,也是不匹配

class Solution {public boolean isValid(String s) {Stack <Character> stack = new Stack<>();for(int i = 0 ;i<s.length();i++){//取出字符char ch = s.charAt(i);if(ch == '(' || ch == '{' || ch == '['){stack.push(ch);}else{//判空if(stack.empty()){return false;}//比较char chs = stack.peek();if(chs == '(' && ch == ')' || chs == '{' && ch == '}' || chs == '[' && ch == ']'){stack.pop();}else{//说明剩下的右边的元素根本就不是括号,可能是其他字符//比如((??这样return false;}}}//如果此时for循环走完了你的栈中还有元素,也就是说没有匹配完if(!stack.empty()){return false;}//当上述所有条件头部满足,说明就删完了,匹配成功return true;}
}
3. 逆波兰表达式求值

我们首先明白什么是逆波兰表达式,我们正常的表达式是这样的,比如2*(3+5)
但是计算机的计算器在计算的时候是不知道我们人类的运算符优先规则去算的,那是怎么搞的呢
你看,逆波兰表达式核心就是把符号往后移,看我演示
M=(3+5)M = (3+5)M=(3+5),则M的逆波兰表达式为35+35+35+,之后整体式子的逆波兰表达式是$ 2M* $,带入M后就是$2 35+ * ,那此时计算就是,那此时计算就是,那此时计算就是 3+5=8 $,再2∗8=162*8=1628=16
画图就是这样的
image-20250724173842687
那我们直接来写题吧

class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack();for(int i = 0;i<tokens.length;i++){if(!isOperator(tokens[i])){stack.push(Integer.parseInt(tokens[i]));}else{//注意两个数的出栈顺序int num1 = stack.pop();int num2 = stack.pop();switch(tokens[i]){case "+"://算出的结果要压入栈中stack.push(num2+num1);break;case "-":stack.push(num2-num1);break;case "*":stack.push(num2*num1);break;case "/":stack.push(num2/num1);break;}}}return stack.pop();}private boolean isOperator(String operator){if(operator.equals("+")||operator.equals("-")||operator.equals("*")||operator.equals("/")){return true;}return false;}
}
4. 求最小栈元素

题目链接
就是要求栈中最小的元素,因为栈不可以倒着遍历,因此我们只能用两个栈,一个普通栈存数字,另一个最小值栈存放当前栈中最小数字
当我不断的压普通栈,如果压的数字有比当前存放最小值的栈的栈顶元素小的话,最小值的栈顶元素就变成当前压入普通栈大的元素
这样当我普通栈出栈的时候,如果比我最小栈栈顶元素一样,那就一起出,否则就只是普通栈出
这样当我后续删除普通栈元素时,每一次都能在最小栈中找到当前普通栈中的最小值

class MinStack {private Stack<Integer> stack;private Stack<Integer> minStack;;public MinStack() {stack = new Stack<>();minStack = new Stack<>();}public void push(int val) {//先压入普通栈再判断stack.push(val);//判空if(minStack.empty()){//最小值栈首次压入元素minStack.push(val);}else{//只有当压入普通栈的元素比最小值栈的栈顶元素小的时候//此时压入普通栈的数字才要同时压入最小值栈if( val <= minStack.peek()){minStack.push(val);}}}public void pop() {//判空if(stack.empty()){return;}//如果普通栈栈顶元素和最小值栈栈顶元素相等,要一起弹出int val = stack.pop();if(val == minStack.peek()){minStack.pop();}}public int top() {//判空if(stack.empty()){return -1;}return stack.peek();}public int getMin() {return minStack.peek();}
}

3. 单链表实现栈

入栈我们采用头插法,出栈我们采用删除头节点方法,此时它们时间复杂度都是O(1)
假如你入栈采用尾插法,还要遍历去找尾巴,麻烦,时间复杂度是O(n)
假如你对单链表的尾节点加上last引用,入栈没问题了可是你出栈还不是要删除尾节点,还不是要找其前一个节点,时间复杂度还是O(n)
但是,如果你采用双向链表,就可以实现,而且双向链表本身就有实现Deque接口,我们说过这是跟栈和队列有关的接口

public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

使用双向列表,我们就能保证出栈和入栈的时间复杂度都是O(1)


文章错误不可避免,期待您的指正,我们共同进步

Git码云仓库链接

之前遗留的方法,有顺序表和链表,还有用链表表示栈

END
http://www.dtcms.com/a/595070.html

相关文章:

  • 淮南矿业集团廉政建设网站新开网店自己如何推广
  • 七.二分算法
  • 怎么用视频做网站首页学校让做网站做完怎么交
  • 注册公司费用要多少厦门seo大佬
  • 做网站填素材wordpress手机网站模板制作
  • 有经验的番禺网站建设綦江建设银行网站
  • 网站 备案信息开发网站用php还是jsp
  • 编程基础核心知识(2)
  • mui做网站兰州网站seo服务
  • PiliPlus 1.1.5-pre | 纯净无广开源的b站第三方,非常好用
  • OpenTenBase V5的全新简易安装
  • 普通电抗器电压校验:短路时校验线残压:
  • 建网站的方案免费建立移动网站吗
  • 网站制作设计正规公司好用的黄页网
  • 中国建设银行积分网站建立微信公众号步骤
  • 郑州做网站kuihuakeji昆明定制化网站建设
  • 洞头区网站建设收费网站建设广告图片
  • 菏泽网站建设优惠臻动传媒什么是整合营销概念
  • 奉贤庄行网站建设中装建设网站
  • 网站聊天代码网片机
  • 合肥网站设计高端公司网络课程网站模板
  • 月嫂的个人简历网站模板化妆品企业网站案例大全
  • 北京机建网站一级造价工程师成绩查询
  • 网站配色的原理和方法wordpress分类页数量
  • 建设网站网站长春 网络设计
  • 中型 GPU 服务集群监控方案(10-50 节点)
  • 织梦网站如何做seo软件开发模型名词解释
  • 厦门网站设计多少钱常州第一门户网
  • 如何建设万网网站搜索引擎优化seo课程总结
  • 多个wordpress站点同步手机+显示器自适应wordpress+主题