Java ArrayDeque - offerLast & pollFirst vs offerFirst & pollLast

问题描述

我正在做一些简单的算法问题并尝试使用 arraydeque

例如这个:

https://leetcode.com/problems/maximum-depth-of-binary-tree/submissions/

在使用 BFS 时,我注意到 offerLast & pollFirst / offerFirst & pollLast 都给出了相同(正确)的答案。

是否有关于何时使用哪个的最佳实践?由于这应该是一个队列,我认为我们应该提供最后并使用 pollFirst。但是为什么 offerFirst / pollLast 也能用呢?

 public int maxDepth(TreeNode root) {
        // do BFS
        if (root == null) return 0;
        
        int depth = 0;
        arraydeque<TreeNode> queue = new arraydeque();
        queue.offerLast(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            for (int i = 0; i < size; i++){
                TreeNode curr = queue.pollFirst();
                if (curr.left != null) queue.offerLast(curr.left);
                if (curr.right != null) queue.offerLast(curr.right);
            }
            depth++;
        }
        
        return depth;
    }

另外,我知道我们不需要队列为 arraydeque 类型。只是一个简单的队列就可以工作,队列只提供认为先进先出实现(offerLast,pollFirst)的报价/轮询

解决方法

但是为什么 offerFirst / pollLast 也可以工作?

因为队列的“开始”和“结束”实际上只是随意决定的。

您可以将第一个元素称为“开始”,将最后一个元素称为“结束”。在这种情况下,offerLast 入队,pollFirst 出队。

由于数组双端队列是线性数据结构,您可以“翻转它”并说,我将第一个元素称为队列的“结束”,将最后一个元素称为队列的“开始”。如果您这样想,那么您将通过调用 offerFirst 入队并通过 pollLast 出队。

解释这一点的另一种方法是表明这只是两种观点:

假设我们站在双端队列的两端。我们都认为离我们最近的元素是双端队列的“第一个元素”。

   the deque;
  a b c d e f g h
^                 ^
|                 |
you               me

您在 a 旁边放置了一个新元素。从您的角度来看,这是 offerFirst。从我的角度来看,你会做offerLast

现在假设您删除了 h。从您的角度来看,这是 pollLast。从我的角度来看,这看起来像 pollFirst - 您正在删除“最后一个元素”,但它是我的“第一个元素”。

但是,请注意,官方决定第一个元素是队列的开头,最后一个元素是结尾——这就是ArrayDeque实现Queue接口的方式——所以如果你从 Queue 调用方法,比如 offer,它会调用 offerLast

虽然如果你有自己的开始和结束的概念它仍然有效,但遵循“开始”和“结束”的官方定义仍然是一个好习惯(实际上只需使用offer和{{1 }}!)。如果您使用 pollpollLast,如果您将双端队列传递给另一段需要 offerFirst 的代码,您的代码可能无法工作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...