我有两个ArrayList,例如:
ArrayList a = new ArrayList();
a.add(10);
a.add(35);
a.add(51);
ArrayList b = new ArrayList();
b.add(24);
b.add(46);
b.add(81);
我需要创建一个函数,该函数在排序查询中将元素从B放入A。 (在我看来,它必须检查A和B中相同位置的元素,并在10和35之间放置24,在35和51之间放置46,最后一个是81)。 我有:
public static void merge(ArrayList a, ArrayList b)
{
a.addAll(b);
Collections.sort(a);
}
但这不是一种有效的算法(N ^ 2)。 有效率更高的吗?
答案 0 :(得分:1)
此实现是一个稳定的,自适应的,迭代的合并排序, 当输入数组为时,所需的比较少于n lg(n)次 部分排序,同时提供传统的性能 输入数组随机排序时的mergesort。如果输入数组 几乎排序,实施大约需要n 比较。临时存储要求从很小的常量开始变化 用于将几乎排序的输入数组随机转换为n / 2个对象引用 有序的输入数组。
此实现的复杂度为O(n lg(n))。大多数时候甚至更低,尤其是在输入几乎被排序的情况下。 Java版本之间可能会有所不同,但是O(n lg(n))相当可靠。
回到您的算法,我们可以这样说
a.addAll(b); // requires O(n)
Collections.sort(a); // requires O(n lg(n))
所以它永远不会比O(n lg(n))更糟糕。
答案 1 :(得分:0)
正如您所说的那样,对这两个列表进行了排序,然后有一种O(N)方式来合并这两个列表。
static List<Integer> merge(List<Integer> a, List<Integer> b) {
List<Integer> merged = new ArrayList<>(a.size() + b.size());
int ai = 0, bi = 0;
while (ai < a.size() && bi < b.size()) {
if (a.get(ai) < b.get(bi))
merged.add(a.get(ai++));
else
merged.add(b.get(bi++));
}
while (ai < a.size())
merged.add(a.get(ai++));
while (bi < b.size())
merged.add(b.get(bi++));
return merged;
}