数据结构 Java数据结构 --- 栈和队列,2024年最新java特性面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

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

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

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

return null;

}

return elem[head];

}

}

3. 双端队列 (Deque)

===================================================================================

3.1 概念


双端队列(deque) 是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。

那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

4. java 中的栈和队列

==================================================================================

Stack

| 方法 | 解释 |

| :-- | :-- |

| E push(E item) | 压栈 |

| E pop() | 出栈 |

| E peek() | 查看栈顶元素 |

| boolean empty() | 判断栈是否为空 |

Stack方法的演示:

public static void main(String[] args) {

Stack stack = new Stack<>();

//压栈

stack.push(1);

stack.push(2);

stack.push(3);

stack.push(4);

//查看栈顶元素

System.out.println(stack.peek());

//出栈

int ret = stack.pop();

System.out.println(ret); //4

ret = stack.pop();

System.out.println(ret); //3

ret = stack.pop();

System.out.println(ret); //2

ret = stack.pop();

System.out.println(ret); //1

//判断栈是否为空

System.out.println(stack.empty());

//此时栈为空 如果 查看栈顶元素 或者 出栈 会报异常(EmptyStackException)

System.out.println(stack.peek());

System.out.println(stack.pop());

}

运行结果:

在这里插入图片描述

Queue

| 错误处理 | 抛出异常 | 返回特殊值 |

| :-- | :-- | :-- |

| 入队列 | add(e) | offer(e) |

| 出队列 | remove() | poll() |

| 队首元素 | element() | peek() |

Deque

| 头部/尾部 | 头部元素(队首) | 尾部元素(队尾) |

| — | — | — |

| 错误处理 | 抛出异常 | 返回特殊值 | 抛出异常 | 返回特殊值 |

| 入队列 | addFirst(e) | offerFirst(e) | addLast(e) | offerLast(e) |

| 出队列 | removeFirst() | pollFirst() | removeLast() | pollLast() |

| 获取元素 | getFirst() | peekFirst() | getLast() | peekLast() |

总结:

Stack:

push ,pop,peek.当当前是一个空栈的,再去pop或者peek就会产生异常.

Queue:

add,remove,element 如果当前操作失败就会抛出异常;

offer,poll,peek 如果操作失败就会返回一个错误值;

5. LeetCode 题目

==================================================================================

第一题 : 有效的括号


有效的括号

LeetCode 20:

描述:

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。

  2. 左括号必须以正确的顺序闭合。

解题思路:

**1. 遍历字符串,依次取出字符串中的字符.

1.1 如果取出的字符串为左括号例如’(’,’[’,’{’.就放入栈中

1.2 如果取出的字符串为右括号例如’)’,’]’,’}’.就和栈顶元素比较是否匹配.

a) 匹配就出栈,然后继续遍历.

b) 不匹配就直接返回false

1.3 如果栈为空,且取出的字符是右括号,则返回false没有例如字符串"]()"

2. 遍历结束后,判断是否栈为空

2.1 如果为空 则满足题意 return true;

2.2 如果不为空 表示没有足够匹配的字符, return false; 如字符串"["**

画图解析:

在这里插入图片描述

在这里插入图片描述

代码实现:

public boolean isValid(String str) {

Map<Character,Character> map = new HashMap<>();

map.put(‘(’,‘)’);

map.put(‘[’,‘]’);

map.put(‘{’,‘}’);

//1.先创建一个栈,栈中保存字符类型即可

Stack stack = new Stack<>();

//2.遍历字符串的每个字符

for (int i = 0; i < str.length(); i++) {

char ch = str.charAt(i);

//3.判断字符 ch 是否为左括号,如果是,就入栈

if (ch == ‘(’ || ch == ‘[’ || ch == ‘{’){

stack.push(ch);

continue;//进入下次循环,取出下一个字符

}

if(stack.empty()){

//如果ch不是左括号,且栈为空,则不是合法括号

return false;

}

//4.判断ch是否是右括号,如果是,就取栈顶元素比较是否相等

char top = stack.pop();//栈顶元素

//以下是3种情况合法情况 – 写法1

/*if(top == ‘(’ && ch == ‘)’) {

continue;

}

if(top == ‘[’ && ch == ‘]’) {

continue;

}

if(top == ‘{’ && ch == ‘}’) {

continue;

}*/

// 判断合法情况 – 写法2

if(map.get(top) == ch){

continue;

}

//如果三种情况都不满足,表示不是合法情况

return false;

}

//遍历完成后 如果栈为空 则满足条件

if(stack.empty()) {

return true;

}

//否则就不合法

return false;

}

第二题 : 用队列实现栈


用队列实现栈

LeetCode 225:

描述:

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。

  • int pop() 移除并返回栈顶元素。

  • int top() 返回栈顶元素。

  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。

  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

解题思路:

**1. 用两个队列来模拟一个栈的效果,引用两个队列 A 和 B .

2. 入栈 : 直接把元素入队到A中即可

3. 出栈 : 因为队列是先进先出的,栈是后进先出的,可以让 A队列 元素出队列然后入队列到 B队列 中,直到A队列中最后一个元素的时候,直接出队列,就实现了后进先出.然后要让A和B交换,始终让入栈到A队列中.

4. 取栈顶元素 : 取栈顶元素就是 出栈 的元素, 不过取栈顶元素要把这个元素返回去

5. 判断是否为空 : A 和 B都为空的时候 就是空栈**

画图解析:

1NETiBAd3d6enp6enp6enp6enp6,size_20,color_FFFFFF,t_70,g_se,x_16)

代码实现:

import java.util.LinkedList;

import java.util.Queue;

public class MyStackByDoubleQueue {

private Queue A = new LinkedList<>();

private Queue B = new LinkedList<>();

public void push(int x) {

// x往A中入队列即可

A.offer(x);

}

public Integer pop() {

if (empty()){

return null;

}

// 把A中的元素往 B 中放

while(A.size() > 1) {

Integer font = A.poll();

B.offer(font);

}

//当循环结束后,A 中 应该只剩1个元素

//这个元素就应该是被出栈的元素

int ret = A.poll();

//交换A和B

swapAB();

return ret;

}

private void swapAB(){

Queue tmp = A;

A = B;

B = tmp;

}

public Integer top() {

if (empty()){

return null;

}

// 把A中的元素往 B 中放

while(A.size() > 1) {

Integer font = A.poll();

B.offer(font);

}

//当循环结束后,A 中 应该只剩1个元素

//这个元素就应该是被出栈的元素

int ret = A.poll();

B.offer(ret); // top 和 pop的区别就是 top要把元素返回去,pop不需要返回去

//交换A和B

swapAB();

return ret;

}

public boolean empty() {

return A.isEmpty() && B.isEmpty();

}

}

第三题 : 用栈实现队列


用栈实现队列

LeetCode 232:

描述:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾

  • int pop() 从队列的开头移除并返回元素

  • int peek() 返回队列开头的元素

  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

解题思路:

**1. 引用2个栈A和B,A专门用来入队列;B专门用来出队列

2. 实现入队列: 先把B中的所有元素都放到A中(因为出栈的时候元素会放入B中),然后直接往A里入栈.

3. 实现出队列: 后进先出的栈实现先进先出的队列,要让A中的所有元素移入B中,先出的的元素就是后进的,此时栈顶就是就是最先进入的元素,B中出栈操作即可

4. 实现取队首元素: 同出队列操作,把A所有元素放入B中,然后取B的栈顶元素就是队首元素.

5. 判空: A 和 B 都为空.**

画图解析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码实现:

import java.util.Stack;

public class MyQueueByDoubleStack {

private Stack A = new Stack<>();

private Stack B = new Stack<>();

public void push(int x) {

//1.先将B中的元素 放入 A 中

while (!B.isEmpty()){

int tmp = B.pop();

A.push(tmp);

}

//2.把新元素放入A中

A.push(x);

}

public Integer pop() {

//1.如果为空 直接返回

if(empty()){

return null;

}

//2.把A中的元素都给B

while(!A.isEmpty()){

int tmp = A.pop();

B.push(tmp);

}

//3.针对B进行出栈

return B.pop();

}

public Integer peek() {

//1.如果为空 直接返回

if(empty()){

return null;

}

//2.把A中的元素都给B

while(!A.isEmpty()){

int tmp = A.pop();

B.push(tmp);

}

//3.取B的栈顶元素

return B.peek();

}

public boolean empty() {

return A.isEmpty() && B.isEmpty();

}

}

第四题 : 最小栈


最小栈

LeetCode 155:

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。

  • pop() —— 删除栈顶的元素。

  • top() —— 获取栈顶元素。

  • getMin() —— 检索栈中的最小元素。

解题思路:

**1. 引用2个栈A和B, A按照正常栈的规则入栈出栈,B存放的是A的最小值以及A历史的最小值

2. 实现入栈操作: A中: 直接入栈 . B中: 取要入栈的值 和 B栈顶元素比较,把较小值入栈到B中.

3. 实现出栈操作: A 和 B 一起出栈

4. 实现取栈顶元素操作: 直接取 A 栈顶元素

5. 实现取最小值操作: 直接取 B 栈顶元素**

画图解析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码实现:

import java.util.Stack;

public class MinStack {

private Stack A = new Stack<>();

private Stack B = new Stack<>();

public void push(int x){

//A 直接入栈

A.push(x);

//如果B为空 直接入栈

if(B.isEmpty()){

B.push(x);

return;

}

//如果B不为空,比较x和B栈顶的较小值,将较小值入栈

int min = B.peek();

min = min < x ? min : x;

B.push(min);

}

public Integer pop(){

//如果A为空 直接返回

if(A.isEmpty()){

return null;

}

//B和A同时出栈

B.pop();

return A.pop();

}

public Integer top(){

//如果A为空 直接返回

if(A.isEmpty()){

return null;

}

return A.peek();

}

public Integer getMin(){

//如果B为空 直接返回

if(B.isEmpty()){

return null;

}

//B的栈顶即使最小元素

return B.peek();

}

}

第五题 : 设计循环队列


设计循环队列

LeetCode 622:

描述:

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。

  • Front: 从队首获取元素。如果队列为空,返回 -1 。

  • Rear: 获取队尾元素。如果队列为空,返回 -1 。

  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。

  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。

  • isEmpty(): 检查循环队列是否为空。

  • isFull(): 检查循环队列是否已满。

解题思路:

**1. 循环队列 运用数组实现. head和tail是下标,head位置始终都是队首的元素;tail位置始终都是队尾的下一个元素 有效元素个数[ head, tail) 左闭右开

2. 入队列 : 把新元素放到 tail 位置上,同时 tail++.

3. 出队列 : 取出 head 位置的元素,同时 head++.

4. 空队列 : 有效元素个为0

5. 满队列 : 有效元素个数等于数组长度

6. 注意当head 和 tail达到 元素上线时,回到最开始的位置.**

画图解析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码实现:

public class MyCircularQueue {

private int[] elem;

private int head = 0;//队首元素下标

private int tail = 0;//队尾下一个元素下标

private int size = 0;//有效元素个数

/**

  • 构造器,设置队列长度为 k 。

  • @param k 队列长度

*/

public MyCircularQueue(int k) {

this.elem = new int[k];

}

/**

  • 向循环队列插入一个元素。如果成功插入则返回真。

  • @param value 插入元素

  • @return

*/

public boolean enQueue(int value) {

//队满就无法入队 返回false

if(size == elem.length){

return false;

}

elem[tail] = value;

tail++;

//tail>=队列长度 要归零

if(tail >= elem.length){

tail = 0;

}

size++;

return true;

}

/**

  • 从循环队列中删除一个元素。如果成功删除则返回真。

  • 队头出

Java核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的

image

image

image

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

/**

  • 向循环队列插入一个元素。如果成功插入则返回真。

  • @param value 插入元素

  • @return

*/

public boolean enQueue(int value) {

//队满就无法入队 返回false

if(size == elem.length){

return false;

}

elem[tail] = value;

tail++;

//tail>=队列长度 要归零

if(tail >= elem.length){

tail = 0;

}

size++;

return true;

}

/**

  • 从循环队列中删除一个元素。如果成功删除则返回真。

  • 队头出

Java核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的

[外链图片转存中…(img-qNdZyE92-1713711381785)]

[外链图片转存中…(img-fYMAt6ys-1713711381786)]

[外链图片转存中…(img-maIyV9tm-1713711381787)]

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-GJO5nl4m-1713711381787)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值