Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在O(1)时间内返回k大小数组的前n个元素_Java_Arrays_Algorithm - Fatal编程技术网

Java 在O(1)时间内返回k大小数组的前n个元素

Java 在O(1)时间内返回k大小数组的前n个元素,java,arrays,algorithm,Java,Arrays,Algorithm,给定一个大小为k的数组,并且前n个元素分配了一个非空引用,那么在Java中,如何返回一个只包含大小为n的前n个元素的数组呢 显然,您可以通过创建一个新的k大小的数组来进行深度复制,然后在初始数组中迭代n次,每次迭代时传输元素,但这将是一个O(n)操作 从我对数组如何存储在内存中的理解来看,我认为可能只需将数组的length属性从k更改为n,然后返回初始数组的引用 作为一种伪方法: public Foo[] head(Foo[] arr, int n) { arr.length = n;

给定一个大小为k的数组,并且前n个元素分配了一个非空引用,那么在Java中,如何返回一个只包含大小为n的前n个元素的数组呢

显然,您可以通过创建一个新的k大小的数组来进行深度复制,然后在初始数组中迭代n次,每次迭代时传输元素,但这将是一个O(n)操作

从我对数组如何存储在内存中的理解来看,我认为可能只需将数组的length属性从k更改为n,然后返回初始数组的引用

作为一种伪方法:

public Foo[] head(Foo[] arr, int n) {
    arr.length = n;
    return arr;
}
我想知道是否可以做些什么来产生一个恒定时间的操作,但我担心这可能是不可能的,因为Java不支持指针算术之类的东西

如果这是不可能的,那么提供相同结果的最快方法是什么。(列表而非数组)

但是,问题总是一样的。保存n的值和数组。你已经做完了。你可以用它们来做同样的事情,你可以用一个不同的假数组来假装大小不同,只需假装数组大小为n,然后使用数组

如果你必须的话

List<MyClass> subArray = Arrays.asList(array).subList(index, index2);
List subArray=Arrays.asList(array).subList(index,index2);

如果必须使用原始数组而不是
ArrayList
,则
数组
具有所需的功能。如果您查看源代码,这些绝对是获取数组副本的最佳方法。它们确实有一些防御性编程,因为如果您向其提供不合逻辑的参数,则
System.arraycopy()
方法会抛出大量未经检查的异常

您可以使用从第一个元素复制到第n个元素的任何一个元素,复制到新的较短数组中

public static <T> T[] copyOf(T[] original, int newLength)
将指定数组的指定范围复制到新数组中。 范围(from)的初始索引必须介于零和之间 原始长度,包括在内。原始[from]处的值放入 副本的初始元素(除非from==original.length或 从==到)。原始数组中后续元素的值为 放置到副本中的后续元素中。最后一个索引是 必须大于或等于from的范围(到)可以是 大于original.length,在这种情况下,所有 索引大于或等于的副本的元素 原始长度-从。返回数组的长度将为- 从…起结果数组与原始数组的类完全相同 数组


3035 public static T[]更多…copyOfRange(U[]原件,int-from,int-to,classThank)。我知道List.subList()但不幸的是,我被限制在方法末尾返回数组。:/然后就没有了。只需使用array.CopyOf(n),这是唯一合理的解决方案。而且内部复制例程非常快。就目前而言,它是使用System.arrayCopy()移动数据的最快方法,而这正是copyof在内部使用的方法。在O(1)中无法做到这一点时间。Java中数组的长度无法更改,因此您需要创建一个新的数组。Jarrod的回答提供了有关如何正确执行此操作的详细信息。@Math谢谢,我只是想知道是否可以更快。谢谢。这两个实用程序函数都使用System.arraycopy,它与新数组大小成线性关系。恒定时间是不可能的吗在这种情况下是什么?这是正确的答案。恒定时间是不可能的。这是最好的。你能得到你想要的东西的唯一方法是使用类似于
迭代器的东西。过滤器(iterable,谓词)
在Guava中起作用。它们是惰性的,只在被访问时处理项目。但它们不是原始数组,这是高效(时间和空间)的唯一方法获取一个子数组并将其保持为原始数组。恒定时间不是不可能的,考虑到您的限制,这是不可能的。如果您想要恒定时间,只需将n的值与数组一起传递,就知道数组的前n个元素很重要。但鉴于他要求它保持为一个数组,您必须复制n个元素,这样您就完蛋了。我提供了一个O(1)解决方案,因为您可以提供一个备份数组的备份子列表()。asList()但它是错误的类型。但这两种方法都只是包装数据并为您保存n的值。
2770
2771    public static <T,U> T[] More ...copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2772        T[] copy = ((Object)newType == (Object)Object[].class)
2773            ? (T[]) new Object[newLength]
2774            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
2775        System.arraycopy(original, 0, copy, 0,
2776                         Math.min(original.length, newLength));
2777        return copy;
2778    }
public static <T> T[] copyOfRange(T[] original, int from, int to)
3035    public static <T,U> T[] More ...copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
3036        int newLength = to - from;
3037        if (newLength < 0)
3038            throw new IllegalArgumentException(from + " > " + to);
3039        T[] copy = ((Object)newType == (Object)Object[].class)
3040            ? (T[]) new Object[newLength]
3041            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
3042        System.arraycopy(original, from, copy, 0,
3043                         Math.min(original.length - from, newLength));
3044        return copy;
3045    }