Java 在O(1)时间内返回k大小数组的前n个元素
给定一个大小为k的数组,并且前n个元素分配了一个非空引用,那么在Java中,如何返回一个只包含大小为n的前n个元素的数组呢 显然,您可以通过创建一个新的k大小的数组来进行深度复制,然后在初始数组中迭代n次,每次迭代时传输元素,但这将是一个O(n)操作 从我对数组如何存储在内存中的理解来看,我认为可能只需将数组的length属性从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;
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 }