有效地从ArrayList获取子列表

时间:2015-08-25 19:01:51

标签: java algorithm arraylist time-complexity

我的问题

我有一个固定大小的ArrayList,其中包含自定义变量。尽管ArrayList具有固定的大小,但有时其中很多实际上都是null。问题是我需要返回没有null变量的ArrayList。 需要注意的一件重要事情: ArrayList首先包含所有非空项,然后是它们下面的所有空值,例如,元素是没有混合。示例:[非null,非null,.... null,null,null]

我的解决方法

我创建了一个for循环,它检查(从最后到第一个索引)ArrayList中的每个元素,以确定它是否为null。如果为null,那么我将调用此代码:

for (i = size-1; i >=0 ; i--) {
    groupList = new ArrayList<>(groupList.subList(0, i));
}

我的问题

如果ArrayList太大,这个方法可能特别慢(或不是?)。我想知道是否存在更好,更友好的解决方案。 AFAIK .subList方法很昂贵。

2 个答案:

答案 0 :(得分:5)

您可以使用binary search的变体,其自定义比较器位于:

  • 两个元素都为null / not null?他们是平等的
  • 只有一个元素为空? none null是&#34;较小&#34;。

您正在寻找第一个null元素。

这将花费O(logn)时间,其中n是数组的大小。

但是,将ArrayList的子列表设为非空(假设您要将其复制到新的列表对象),将是复制元素的线性时间,因为您必须&# 34;触摸&#34;他们每个人。

这为您提供了O(logn + k)的总时间复杂度,其中k是非null元素的数量,n是数组的大小。

答案 1 :(得分:1)

根据您所有出色的建议,我修改了原始方法,以便我可以将最后(第一个)空项目位置并仅调用一次.subList方法。这是:

int lastNullIndex = size - 1;

for (i = lastNullIndex; i >= 0; i--) {
    if (null == groupList.get(i)) {
        lastNullIndex = i;
    } else {
        break;
    }
}

groupList = new ArrayList<>(groupList.subList(0, lastNullIndex));
return groupList;

如果您认为可以进一步修改以便获得更好的性能,请告诉我们。