从Integer java

时间:2018-05-03 13:16:03

标签: java list arraylist time-complexity

我正在为以下问题寻找更好的解决方案(明智的时间和复杂性):

给出整数列表。首先打印所有第一个元素,然后是所有第二个元素,依此类推。

示例:{{1,2,3}, {5,4,6}}打印1,5,2,4,3,6

解决方案1:我可以使用两个for循环迭代列表列表,但是时间复杂度将增加到O(n^2)。有没有更好的方法来使用O(n)来实现上述结果?

2 个答案:

答案 0 :(得分:1)

简短回答:

答案很长:说你想在一个循环中完成它。如果所有内部列表具有相同的长度,如果您对列表元素(例如数组列表)具有快速随机访问权限,则可以计算下一个元素的位置。伪Java的代码:

int totalElements = outerListSize * innerListSize;
for(int targetPos = 0; targetPos < totalElements; targetPos++) {
    //For the outer list, choose the next index until reaching
    //the end, then roll over
    int outerIndex = targetPos % outerListSize;
    //For the inner lists, choose 0 until the outer lists roll
    //over, then 1, ...
    int innerIndex = targetPos / outerListSize;

    targetList.add(targetPos, outerList.get(outerIndex).get(innerIndex));
}

但是这不会为你节省任何东西,因为现在你有一个从0到n * n的单循环 - 你还有O(n2)

答案 1 :(得分:0)

嗯,一切都取决于你n的意思。

通常n是输入的大小,在你的情况下,输入的大小是所有列表中所有元素的数量(所有列表大小的总和),然后有线性解决方案需要O(n),因为你只访问每个元素一次。 这是我的实现,但是有多种方法可以执行此操作,我假设您声称需要O(n^2)时间的解决方案实际上也是线性的并且需要O(n)

    List<List<Integer>> list = new ArrayList<>();
    list.add(Arrays.asList(1, 2, 3));
    list.add(Arrays.asList(5, 4, 6));

    Map<Integer, List<Integer>> map = new HashMap<>();
    for (List<Integer> integers : list) {
        for (int i = 0; i < integers.size(); i++) {
            map.computeIfAbsent(i, k -> new ArrayList<>()).add(integers.get(i));
        }
    }

    int i = 0;
    while (map.containsKey(i)) {
        for (Integer value : map.get(i)) {
            System.out.print(value + ", ");
        }
        ++i;
    }

但是,如果我错了并且您将n定义为列表数量,那么我们就会遇到问题,因为列表大小是独立的列表数量。因此,假设在最坏的情况下,您的一个内部列表的大小为m,那么整体复杂度为O(nm)。而且您显然无法做到这一点,因为您总体上{{1}元素,你需要访问列表中的每个元素来打印它。

我认为您无法估算将O(nm)定义为多个列表的算法复杂度,而无需为每个列表定义最坏情况的元素数。