目录
算法要求
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断该字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
比如: "()"、"()[]{}"、"{[]}" 都是有效字符串,而 "(]" 、"([)]" 则不是
解题思路
1、我们可以通过一个HashMap来存放所有括号类型,右括号为键,左括号为值。
2、遍历字符串,如果是左括号就入栈,右括号则和栈顶元素作比较,如果刚好形成一对完成括号,则继续。否则说明不是一对完整括号。
3、遍历结束后判断栈中元素是否全部取出,只有全部取出,说明这个字符串中符号成对出现。
- /**
- * 判断这个符号字符串中符号是否成对出现
- * @param s
- * @return
- */
- public static boolean isValid(String s){
- //创建一个hashMap把所有符号都存入
- Map
maps =new HashMap<>(); - maps.put(')','(');
- maps.put(']','[');
- maps.put('}','{');
-
- Stack
stack =new Stack<>(); - //将字符串转换为字符数组
- char[] chars= s.toCharArray();
- //遍历字符数组
- for (int i = 0; i
- //判断这个符号是否为右括号
- if (maps.containsKey(chars[i])){
- //栈中如果为空赋值为#否则取出栈顶元素
- char isEmpty =stack.isEmpty()?'#':stack.pop();
- //判断这个右括号对应的左括号是否等于栈顶元素
- if (isEmpty!=maps.get(chars[i])){
- return false;
- }
- }else {
- //如果为左括号则入栈
- stack.push(chars[i]);
- }
- }
- //遍历结束 如果栈中还有元素 则说明其中没有对应括号
- return stack.isEmpty();
- }
测试
- public static void main(String[] args) {
- System.out.println("[]{}()中符号是否成对出现:"+isValid("[]{}()"));
- System.out.println("{([})}中符号是否成对出现:"+isValid("{([])}"));
- System.out.println("([)]中符号是否成对出现:"+isValid("([)]"));
- System.out.println("(()中符号是否成对出现:"+isValid("(()"));
- }
测试结果

反转字符串
这个就直接运用栈的后进先出原则,把字符串依次入栈再出栈就行。
- /**
- * 字符串的反转
- * @param s
- * @return
- */
- public static String stringReversal(String s){
- Stack
stack =new Stack<>(); - for (int i =0;i
- stack.push(s.charAt(i));
- }
- String news="";
- for (int i = 0, len = stack.size(); i < len; i++) {
- news+=stack.pop();
- }
- return news;
- }
测试
- public static void main(String[] args) {
- String ts ="the shy";
- String yskm ="you should know me";
- System.out.println("ts反转前:"+ts);
- System.out.println("ts反转后:"+stringReversal(ts));
- System.out.println("yskm反转前:"+yskm);
- System.out.println("yskm反转后:"+stringReversal(yskm));
-
- }
测试结果

循环队列的实现
和队列相比,循环队列的优点就是不会造成假溢出,因为当队尾到达数组的末尾时,如果数组头部还有空间,则会继续向头部移动。会形成一个循环,除非队尾与队头相邻,则队列才满。
- /**
- * 循环队列的实现
- * @author CC
- * @version 1.0
- * @since2023/9/28
- */
- public class CircularQueue {
- private int[] array;//使用数组来存储
- private int front;//对头
- private int rear;//队尾
-
- //实例队列并设置初始容量
- public CircularQueue(int capacity){
- this.array =new int[capacity];
- }
-
-
- /**
- * 入队
- * @param element
- * @throws Exception
- */
- public void offer(int element) throws Exception {
- //队尾不能存值 所以队尾的下一个元素如果是队头 说明队列已满
- if ((rear+1)%array.length==front){
- throw new Exception("队列已满!");
- }
- //将值存入队尾
- array[rear] =element;
- //队尾向后移动
- rear =(rear+1)%array.length;
- }
-
- /**
- * 出队
- * @return
- * @throws Exception
- */
- public int pull() throws Exception {
- //如果队头等于队尾 则只有一个可能 就是该队为空
- if (rear==front){
- throw new Exception("队列为空!");
- }
- //取出队头元素
- int deQueueElement =array[front];
- //队头向后移动
- front=(front+1)%array.length;
- return deQueueElement;
- }
-
- /**
- * 输出队列
- * @return
- */
- @Override
- public String toString() {
- StringJoiner sj =new StringJoiner("-");
- for (int i=front;i!=rear;i=(i+1)%array.length){
- sj.add(String.valueOf(array[i]));
- }
- return sj.toString()+"-队尾";
- }
- }
测试
- /**
- * @author CC
- * @version 1.0
- * @since2023/9/28
- */
- public class CTest {
- public static void main(String[] args) throws Exception {
- CircularQueue queue = new CircularQueue(5);
- queue.offer(1);
- queue.offer(2);
- queue.offer(3);
- queue.offer(4);
- System.out.println("接连将1、2、3、4分别入队后:"+queue);
- queue.pull();
- System.out.println("发生一次出队后:"+queue);
- queue.offer(5);
- System.out.println("将5入队后:"+queue);
- }
- }
测试结果

使用队列实现栈
实现原理
通过创建两个队列,一个为出栈队列,一个为入栈队列。首先入栈队列是一直为空的,在入栈时先将元素存入入栈队列,再将出栈队列的元素依次存入入栈队列,这就将刚入元素就被放入了队尾。然后交换两个队列,出栈时将出栈队列队头元素出栈,也就是最早入栈的元素。
- /**
- * @author CC
- * @version 1.0
- * @since2023/9/30
- */
- public class MyStack {
- private Queue
queue1; //出栈队列 - private Queue
queue2; //入栈队列 -
- /**
- * 初始化栈 底层使用链表存储
- */
- public MyStack() {
- queue1 = new LinkedList
(); - queue2 = new LinkedList
(); - }
-
- /**
- * 入栈
- * @param item
- */
- public void push(int item) {
- //将元素存入队列2
- queue2.offer(item);
- //将队列1中元素依次出队 并存入队列2
- while (!queue1.isEmpty()){
- queue2.offer(queue1.poll());
- }
- //交换队列1 与 队列2
- Queue
temp = queue1; - queue1 = queue2;
- queue2 = temp;
- }
-
- /**
- * 出栈
- * @return
- */
- public int pop(){
- return queue1.poll();
- }
-
- /**
- * 获取栈顶元素
- * @return
- */
- public int top(){
- return queue1.peek();
- }
-
- /**
- * 判断该栈是否为空
- * @return
- */
- public boolean isEmpty(){
- return queue1.isEmpty();
- }
-
-
- /**
- * 输出栈中元素
- * @return
- */
- @Override
- public String toString() {
- StringJoiner sj =new StringJoiner("-");
- for (Integer integer : queue1) {
- sj.add(String.valueOf(integer));
- }
- return "栈顶"+sj.toString();
- }
- }
测试
- /**
- * @author CC
- * @version 1.0
- * @since2023/9/30
- */
- public class MyStackT {
- public static void main(String[] args) {
- MyStack stack =new MyStack();
- stack.push(1);
- stack.push(2);
- stack.push(3);
- stack.push(4);
- System.out.println("1、2、3、4依次入栈后:"+stack);
-
- System.out.println("出栈元素:"+stack.pop());
- System.out.println("出栈一次后:"+stack);
-
- System.out.println("查看栈顶元素(不取出):"+stack.top());
-
- System.out.println("查看栈顶元素后:"+stack);
- System.out.println("该栈是否为空:"+stack.isEmpty());
- System.out.println("出栈元素:"+stack.pop());
- System.out.println("出栈元素:"+stack.pop());
- System.out.println("出栈元素:"+stack.pop());
- System.out.println("该栈是否为空:"+stack.isEmpty());
- }
- }
测试结果

使用栈实现队列
实现原理
创建两个栈,一个为入队栈、一个为出队栈。入队栈的出栈顺序为后进先出。因为出队时,需要把入队栈的元素依次出栈再入栈到出队栈。后进先出的后进先出就为先进先出。所以出队栈的出栈顺序为先进先出。以此来实现和队列相同逻辑,先进先出。
- /**
- * @author CC
- * @version 1.0
- * @since2023/9/30
- */
- public class MyQueue {
- private Stack
inStack =new Stack<>(); //入队栈 - private Stack
outStack =new Stack<>(); //出队栈 -
- /**
- * 入队
- * @param item
- */
- public void offer(int item){
- //将出堆栈中的元素依次放入入队栈中
- while (!outStack.isEmpty()){
- inStack.push(outStack.pop());
- }
- //入队栈入栈
- inStack.push(item);
- }
-
- /**
- * 出队
- * @return
- */
- public int poll(){
- //将入堆栈中的元素依次放入出队栈中
- while (!inStack.isEmpty()){
- outStack.push(inStack.pop());
- }
- //出堆栈出栈
- return outStack.pop();
- }
-
- /**
- * 判断队中是否为空
- * @return
- */
- public boolean isEmpty(){
- return inStack.isEmpty()&outStack.isEmpty();
- }
-
- /**
- * 查看队列元素
- * @return
- */
- @Override
- public String toString() {
- while (!inStack.isEmpty()){
- outStack.push(inStack.pop());
- }
- StringJoiner sj =new StringJoiner("-");
- for (Integer integer : outStack) {
- sj.add(integer.toString());
- }
- return "队尾-"+sj.toString();
- }
- }
测试
- public class MyQueueT {
- public static void main(String[] args) {
- MyQueue myQueue =new MyQueue();
- // 入队
- myQueue.offer(1);
- myQueue.offer(2);
- myQueue.offer(3);
- myQueue.offer(4);
- myQueue.offer(5);
- System.out.println("依次入队1、2、3、4、5后:"+myQueue);
-
- // 出队
- System.out.println("出队:"+myQueue.poll()); // 1
- System.out.println("出队:"+myQueue.poll()); // 2
- System.out.println("出队:"+myQueue.poll()); // 3
- System.out.println("连续三次出队后:"+myQueue);
- // 入队
- myQueue.offer(6);
- myQueue.offer(7);
- myQueue.offer(8);
- System.out.println("依次入队6、7、8后:"+myQueue);
- // 出队
- System.out.println("出队:"+myQueue.poll()); // 4
- System.out.println("出队:"+myQueue.poll()); // 5
- System.out.println("出队:"+myQueue.poll()); // 6
- System.out.println("连续三次出队后:"+myQueue);
- System.out.println("队内是否为空:"+myQueue.isEmpty());
-
- System.out.println("出队:"+myQueue.poll()); // 7
- System.out.println("出队:"+myQueue.poll()); // 8
- System.out.println("队内是否为空:"+myQueue.isEmpty());
- }
- }
测试结果

-
相关阅读:
电脑电源灯一闪一闪开不了机怎么办
汇编基础(1)--ARM32
十二、SpringBoot文件上传使用及流程分析【文件上传参数解析器】
备战数学建模48-数学规划模型终结篇(全)(攻坚战13)
前端面试题JS篇(3)
Opencv 基本操作三 实现各个形态学处理并实现多图展示
精心整理了超详细的Linux入门笔记,零基础也能看懂,一学就会
辅助驾驶功能开发-执行器篇(03)-Mobileye Control Requirements
leetcode-二叉搜索树与双向链表-89
python的/ 和// 学习
-
原文地址:https://blog.csdn.net/c1390527393/article/details/133430258