首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java ArrayDeque应用示例

ArrayDeque 是一个非常高效的双端队列,适合多种场景。接下来列出几种最佳实践场景及代码示例,以帮助理解如何高效地使用 ArrayDeque。

一、栈的替代实现

ArrayDeque 可以替代 Stack 使用,因为它在不需要线程安全的情况下比 Stack 更高效。使用 addFirst 和 removeFirst 方法模拟“后进先出”的栈结构。

示例:

ArrayDeque<Integer> stack = new ArrayDeque<>();

// 压栈操作

stack.addFirst(1);

stack.addFirst(2);

stack.addFirst(3);

// 弹栈操作

while (!stack.isEmpty()) {

System.out.println(stack.removeFirst()); // 输出:3, 2, 1

}

二、队列的替代实现

与 LinkedList 不同,ArrayDeque 是基于数组实现的,避免了链表的节点开销。因此它适合用作普通的队列,在需要“先进先出”(FIFO)的队列操作时可以直接使用 addLast 和 removeFirst。

示例:

ArrayDeque<String> queue = new ArrayDeque<>();

// 入队操作

queue.addLast("A");

queue.addLast("B");

queue.addLast("C");

// 出队操作

while (!queue.isEmpty()) {

System.out.println(queue.removeFirst()); // 输出:A, B, C

}

三、双端队列操作

ArrayDeque 支持在两端添加和删除元素,非常适合需要在两端进行操作的场景。比如,模拟浏览器的前进和后退功能。

示例:

ArrayDeque<String> history = new ArrayDeque<>();

// 用户访问页面

history.addLast("Page1");

history.addLast("Page2");

history.addLast("Page3");

// 后退

System.out.println(history.removeLast()); // 输出:Page3

System.out.println(history.removeLast()); // 输出:Page2

// 重新访问新页面

history.addLast("Page4");

// 最终的历史记录

System.out.println(history); // 输出:[Page1, Page4]

四、广度优先搜索(BFS)算法

在图或树结构的广度优先搜索算法中,ArrayDeque 可以用作队列实现,其 addLast 和 removeFirst 操作非常适合 BFS 的 FIFO 特性。

示例:

class Node {

int value;

List<Node> neighbors;

Node(int value) {

this.value = value;

this.neighbors = new ArrayList<>();

}

}

void bfs(Node start) {

Set<Node> visited = new HashSet<>();

ArrayDeque<Node> queue = new ArrayDeque<>();

queue.addLast(start);

visited.add(start);

while (!queue.isEmpty()) {

Node node = queue.removeFirst();

System.out.println("Visited node: " + node.value);

for (Node neighbor : node.neighbors) {

if (!visited.contains(neighbor)) {

queue.addLast(neighbor);

visited.add(neighbor);

}

}

}

}

五、滑动窗口最大值

常见的滑动窗口算法通常涉及在窗口内的添加和移除操作,一般会使用 ArrayDeque 的双端特性来保持窗口的最大值、最小值或其他数据结构特性。

示例代码:

public int[] maxSlidingWindow(int[] nums, int k) {

if (nums == null || k <= 0) {

return new int[0];

}

int n = nums.length;

int[] result = new int[n - k + 1];

int resultIndex = 0;

ArrayDeque<Integer> deque = new ArrayDeque<>(); // 存储数组的索引

for (int i = 0; i < n; i++) {

// 移除滑动窗口之外的元素

if (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {

deque.pollFirst();

}

// 移除队列中所有比当前元素小的元素

while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {

deque.pollLast();

}

// 将当前元素添加到队列

deque.offerLast(i);

// 当窗口达到大小 k 时,记录窗口的最大值

if (i >= k - 1) {

result[resultIndex++] = nums[deque.peekFirst()];

}

}

return result;

}

滑动窗口的实现:每次滑动窗口向右移动时,只需将窗口左端的元素移出,右端的元素移入。

使用 ArrayDeque 进行入队和出队的操作时间复杂度均为 O(1)。

总体时间复杂度:每个元素最多被加入和移除一次,因此对于 n 个元素,总体时间复杂度为 O(n)。

这个方法也可以扩展用于其他滑动窗口问题,比如最小值、平均值等。

五、最后总结

使用 ArrayDeque 作为栈和队列的替代比 LinkedList 更高效,适用于栈、队列和双端队列操作。ArrayDeque 尤其适合滑动窗口等场景。由于它是基于数组的实现,ArrayDeque 不适合存储过大的数据结构(例如非常深的递归栈)

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OXronYwHjEivrJ8LM_Sqov3A0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券