【问题标题】:If some function parameter recieves List<List<Integer>> nums , then the nums is instantiated by LinkedList or ArrayList?如果某个函数参数收到 List<List<Integer>> nums ,那么 nums 是由 LinkedList 还是 ArrayList 实例化的?
【发布时间】:2021-11-14 18:06:30
【问题描述】:

LinkedListArrayList 都建立在 List 接口之上,而 LinkedList 使用传统的指针技术来构建列表,ArrayList 使用数组来实现 List 功能。那么在使用数字之前可以声明什么是在屏幕后面使用ArrayListLinkedList

我是怎么得到这个问题的?

    public int[] smallestRange(List<List<Integer>> nums) {
        
    }
}

大多数 Leetcode Java 问题都有这种格式的输入。在不知道如何实例化 nums 的情况下,有人如何使用 nums.get(i) 函数(list.get(i) 在 ArrayList 中为 O(1),在 linkedList 中为 O(n))

【问题讨论】:

  • 没有一个,List 是一个接口,你不能(不应该)假设内部表示(当然你可以在运行时检查但不应该)。如果您需要快速实现,请创建自己的受限接口/类或直接编写smallestRange(ArrayList&lt;...&gt; ...)
  • 这是避免list.get(int) 而是使用迭代器的一个很好的理由。

标签: java generics arraylist collections linked-list


【解决方案1】:

99% 的情况下,它将是 ArrayList,而您想在代码中使用 ArrayList。它们使用更少的内存,速度更快,并且利用LinkedList 的代码通常可以重写为使用两个ArrayLists。主要缺点是add() 偶尔会在 O(n) 时间内运行。

有人如何使用 nums.get(i)

你没有。您可以利用 Iterable 的列表并执行诸如 for-each 循环之类的操作:

for (var i : list) {
    ...
}

LinkedListArrayList 都在 O(n) 时间内运行。

技术上,有一个名为RandomAccess 的接口,您可以检查get() 是否为O(1)。不过,你可能不想要它。使用迭代器。

if (list instanceof RandomAccess) {
    list.get(...);
}

【讨论】:

  • 绝对正确:基本上没有理由积极使用LinkedList,甚至Joshua Bloch, who wrote it 也不使用它。大多数时候你不应该关心使用了哪个特定的List 实现。我唯一缺少的是在检查 RandomAccess 时可能有用的解释,如果有的话。
  • @JoachimSauer 在您自己的应用程序中,避免LinkedList 是最简单的策略。但是JDK代码本身使用RandomAccess的检查来切换算法,这是合理的,因为它无法预测应用程序代码是否会使用LinkedList。而LinkedList 在 SO 问题中出现了很多,这表明可能有很多软件仍在使用它。恐怕有些老师给初学者的建议不好……
  • 关于“切换算法”,最明显的例子是使用哪种排序实现。我认为它为 RandomAccess 就地排序,但将非 RandomAccess 列表复制到 ArrayList 中,就地排序,然后替换元素。
  • @DavidEhrmann sort 的默认实现总是进行复制。原因是它由Arrays.sort(…) 支持,无论如何都需要一个数组。只有ArrayListVector 覆盖它以将它们的内部数组直接传递给Arrays.sort(…)。但基本上所有其他操作(reverseshufflefillcopyrotatereplaceAllindexOfSubListbinarySearch)都有这样的开关。
【解决方案2】:

可以是其中任何一个:

  List<List<Integer>> list1 = new ArrayList<>();
        
  List<List<Integer>> list2 = new LinkedList<>();

  int[] x = smallestRange(list1); //works
  int[] y = smallestRange(list2); //also works

你需要让你的代码能够同时满足这两种类型

【讨论】:

  • 其中之一或大量其他可能性,包括第三方代码或您自己的代码。
【解决方案3】:

您不能直接断言 List 接口的默认实现是什么。接口只是一个规范,你有多个列表接口的实现,就像你在图片中提到的那样。

每个实现都会覆盖 List 接口中提到的方法,但它们的逻辑会根据数据结构而有所不同。

现在它完全取决于您根据您的要求想要哪种实现。无论您有空间限制还是时间限制。但是两者都将具有与接口中指定的相同的方法。

根据编码挑战平台,我认为他们指定了调用此方法的代码。你可以在那里检查但如果没有指定,那么他们很可能会选择 ArrayList - 用于时间限制。而且我认为用户不应该担心他们选择的实现。正如我告诉用户应该知道他的要求是什么,然后只选择实现。

【讨论】:

    猜你喜欢
    • 2017-09-13
    • 2019-10-31
    • 2019-11-30
    • 2015-05-29
    • 2014-02-22
    • 2023-03-28
    • 2019-08-24
    • 2022-11-23
    • 2020-12-20
    相关资源
    最近更新 更多