(最新版2022版)剑指offer之队列 栈题解
admin
2024-04-02 09:56:49
0

(最新版2022版)剑指offer之队列 & 栈题解

    • 1、《剑指offer》JZ9 用两个栈实现队列
    • 2、《剑指offer》JZ30 包含min函数的栈
    • 3、《剑指offer》JZ59 滑动窗口的最大值
    • 4、《剑指offer》JZ31 栈的压入、弹出序列
    • 5、《剑指offer》JZ73 翻转单词序列


1、《剑指offer》JZ9 用两个栈实现队列

题目描述:

用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。

数据范围: n\le1000n≤1000
要求:存储n个元素的空间复杂度为 O(n)O(n) ,插入与删除的时间复杂度都是 O(1)O(1)

解题思路:

我们先将栈底和队首对应,栈顶和队尾对应来分析一下队列和栈操作,在这种情况下入队可以看作入栈,难点在于出队。

出队操作的结果是取出队首第一个元素,对应的是取出栈底元素。要取出栈底元素首先要把其他元素出栈,出栈后的元素压入到另一个栈中,取出栈底元素后再把这些元素放回来。

编程实现(Java):

import java.util.Stack;public class Solution {//入栈只对stack1操作,出栈只对stack2操作Stack stack1 = new Stack();Stack stack2 = new Stack();public void push(int node) {stack1.push(node);}public int pop() {//栈2不为空直接pop元素if (!stack2.isEmpty()) {return stack2.pop();//栈2空,栈1不空,把栈1中所有元素装入栈2} else if (!stack1.isEmpty() && stack2.isEmpty()) {while (!stack1.isEmpty()) {stack2.push(stack1.pop());}return stack2.pop();//栈1,栈2都为空,返回-1。} else {return -1;}}
}

2、《剑指offer》JZ30 包含min函数的栈

题目描述:
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。

此栈包含的方法有:
push(value):将value压入栈中
pop():弹出栈顶元素
top():获取栈顶元素
min():获取栈中最小元素

数据范围:操作数量满足 0 \le n \le 300 \0≤n≤300 ,输入的元素满足 |val| \le 10000 \∣val∣≤10000
进阶:栈的各个操作的时间复杂度是 O(1)\O(1) ,空间复杂度是 O(n)\O(n)

解题思路:
要求时间复杂度为O(1),而栈的操作入栈和出栈时间也是O(1),也就是说要在数据入栈的时候同步存好最大值和最小值就要侧重入栈和出栈。在这里我们定义了一个新的minvalues数组作为最小栈。当一个元素入栈时,如果之前的栈为空很明显这个元素就是最小值。当栈不为空时如果当前元素小于最小栈的值则将这个元素的值同步压到最小栈中,否则将最小栈的最小栈(栈顶元素)压到最小栈的栈顶。栈和最小栈同步入栈和出栈即可保证最小栈的栈顶元素是最小值

编程实现:

import java.util.Stack;public class Solution {Stack stack1 = new Stack<>();Stack stack2 = new Stack<>();public void push(int node) {stack1.push(node);if (stack2.isEmpty() || node <= stack2.peek()) {stack2.push(node);}}public void pop() {//if(stack1.peek().intValue() == stack2.peek().intValue()){if (stack1.peek().equals(stack2.peek())) {stack2.pop();}stack1.pop();}public int top() {return stack1.peek();}public int min() {return stack2.peek();}
}

3、《剑指offer》JZ59 滑动窗口的最大值

题目描述:

给定一个长度为 n 的数组 num 和滑动窗口的大小 size ,找出所有滑动窗口里数值的最大值。

例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

窗口大于数组长度或窗口长度为0的时候,返回空。

数据范围: 1 \le n \le 100001≤n≤10000,0 \le size \le 100000≤size≤10000,数组中每个元素的值满足 |val| \le 10000∣val∣≤10000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

解题思路:

解释:

滑动窗口的位置最大值
[1 3 -1] -3 5 3 6 73
1 [3 -1 -3] 5 3 6 73
1 3 [-1 -3 5] 3 6 75
1 3 -1 [-3 5 3] 6 75
1 3 -1 -3 [5 3 6] 76
1 3 -1 -3 5 [3 6 7]7

提示:

  • 你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

分析
我们可以利用双端队列来维护一个单调非递减的队列来表示当前的最大值,由于队列单调非减,队首的元素即为最小元素。

编程实现(Java):

import java.util.*;
public class Solution {public ArrayList maxInWindows(int [] num, int size) {ArrayList list = new ArrayList<>();if (size > num.length || size == 0) {return list;}Deque queue = new LinkedList<>();for (int i = 0; i < num.length; i++) {//num[1, 3, -1, -3, 5, 3, 6, 7]//下标[1, 2, 3],单调队列,保持队列递增while (!queue.isEmpty() && num[queue.peekLast()] < num[i]) {queue.pollLast();}queue.add(i);//如果队列中元素超过size,把最先加入的下标poll()if (queue.peekLast() - queue.peekFirst() >= size) {queue.pollFirst();}//滑动窗口向后移,并加入list中if (i + 1 >= size) {list.add(num[queue.peekFirst()]);}}return list;}
}

4、《剑指offer》JZ31 栈的压入、弹出序列

题目描述:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

  1. 0<=pushV.length == popV.length <=1000
  2. -1000<=pushV[i]<=1000
  3. pushV 的所有数字均不相同

编程实现(Java):

import java.util.*;public class Solution {public boolean IsPopOrder(int [] pushA,int [] popA) {if(pushA.length == 0){return true;}Stack stack = new Stack<>();int k = 0;for(int i = 0; i < pushA.length; i++){stack.push(pushA[i]);while(!stack.isEmpty() && stack.peek().equals(popA[k])){stack.pop();k++;}}return stack.isEmpty();}
}

5、《剑指offer》JZ73 翻转单词序列

题目描述:
描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“nowcoder. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a nowcoder.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

数据范围:1 \le n \le 100 \1≤n≤100
进阶:空间复杂度 O(n) \O(n) ,时间复杂度 O(n) \O(n) ,保证没有只包含空格的字符串


public class Solution {public String ReverseSentence(String str) {str = str.trim();StringBuilder s = new StringBuilder();int i = str.length() - 1;int j = i;while(i >= 0){//找到倒数第一个空格while(i >= 0 && str.charAt(i) != ' ') i--;//将倒数第一个单词拼接到s上s.append(str.substring(i + 1, j + 1) + " ");//清除倒数第一个单词前连续多个空格while(i >= 0 && str.charAt(i) == ' ') i--;j = i;}return s.toString().trim();}
}

相关内容

热门资讯

3秒抢3个,二手溢价超600元... 今天(7月8日)起 迪士尼上新夏日单品 就是下面这几个娃娃 在官方线上平台 这几个娃娃一上线就秒没...
7月11日,凉山彝族火把节等你... 红星新闻网(记者 李婉清)7月8日报道7月8日,省政府新闻办在四川省新闻发布厅举行“万千气象看四川・...
暑假这样过才叫爽!超全攻略让你... 暑假终于来了!是不是已经按捺不住内心的激动,迫不及待想要开启快乐时光了呢?别急,让我为你奉上一份超全...
求姓名藏头诗一首,给女朋友的,... 求姓名藏头诗一首,给女朋友的,她叫刘树红要古体诗七言那种,意境要美要押韵你乃本是天生仙,与我相聚下凡...
希望大家给我介绍几本关于人生经... 希望大家给我介绍几本关于人生经历方面的好书,谢谢了!!!《让方向更清晰!!》作者:爱琳·C卡瑟拉《《...
海贼王萨博在德雷斯罗萨回忆里得... 海贼王萨博在德雷斯罗萨回忆里得知艾斯的死讯是在哪集?没有具体说明在哪集,那只是个回忆片段而已。动漫里...
武林外传里佟掌柜儿时的好友说的... 武林外传里佟掌柜儿时的好友说的是什么地方的方言?一楼的,是陕西话那为什么和佟掌柜说的不一样?是陕西话...
用英语以春节为题的手抄报 春节... 用英语以春节为题的手抄报 春节英语手抄报小学生春节英语手抄报教程关于春节的英语手抄报怎么画春节英语手...
大学生研发校徽月饼是什么样子的... 大学生研发校徽月饼是什么样子的?大学生研发“校徽月饼”走红 原料取材学校培育作物。陕西大学生研发“彩...
《潜伏》中,晚秋是个什么样的人... 《潜伏》中,晚秋是个什么样的人?结局如何晚秋有着悲惨的命运,一直深爱着孙红蕾,最后孙红蕾在香港执行任...
我爱上了我的小学女同桌,我13... 我爱上了我的小学女同桌,我13岁13岁 好小的年龄呀!暗恋两年也不错,主要是你们太小了,现在你们懂得...
TVB出过一个动画是在讲一些章... TVB出过一个动画是在讲一些章鱼小丸子的故事的叫什么?【是在一个类似放学ICY的节目播的】章鱼小超人...
谁有周建龙版的 有声小说 盗墓... 谁有周建龙版的 有声小说 盗墓笔记 7 8 部 分享下 谢谢盗吧首页吧规+资源,甭找了,就没这东西周...
当你一个人在深夜发呆的时候 会... 当你一个人在深夜发呆的时候 会听什么歌?推荐几首好听的额你喜欢悲伤的还是节奏性强的啊?
搞笑一家人剧情 搞笑一家人剧情尤美喜欢谁?我觉得才开始尤美喜欢允浩,允浩也喜欢尤美,只是尤美误会是她爸爸杀了开成嫂的...
跪求好听的歌! 跪求好听的歌!英文歌 中文歌都要 重在好听多来点啊下个,路口,见圣诞结 爱似水仙你若...
我只会打字,对电脑编程不懂怎么... 我只会打字,对电脑编程不懂怎么办?这没有其他的办法,只有深造你要学习吗?
百听不厌的50首经典老歌推荐 百听不厌的50首经典老歌推荐百听不厌的50首经典老歌推荐:1、后来2、光辉岁月3、鬼迷心窍4、大海5...
关于防溺水的手抄报,自己防溺水... 关于防溺水的手抄报,自己防溺水的卡通图片,各位亲,急用啊!
怪物猎人XX烬灭刃斩龙怎么打 怪物猎人XX烬灭刃斩龙怎么打你问怎么打没意义,各人打法不一样,比如咬尾巴大回旋人家直接滚过去输出,你...