列表操作算法太慢了

时间:2017-10-07 12:30:51

标签: java algorithm collections

有一个n个整数的序列a1,a2,...,an。我们需要使用最小元素更改序列中的每个元素,这些元素放在它之前。如果没有这样的元素,我们需要用-1替换它。所有的变化都是同步和独立的。

的示例:

4 3 1 2 1 - > -1 4 3 3 2

5 4 3 2 1 - > -1 5 4 3 2

我的代码太慢,并且在序列太大时没有通过超时错误的测试。如何改善其表现?

这是我的代码:

public static void main(String[] args) throws InterruptedException {
    ArrayList<Integer> list = new ArrayList<>();
    Scanner scanner = new Scanner(System.in);
    int nElements = scanner.nextInt();
    for (int i = 0; i < nElements; i++) {
        list.add(scanner.nextInt());
    }
    ArrayList<Integer> newList = new ArrayList<>();
    for (int i = 0; i < list.size(); i++) {
        int tmp = -1;
        for (int j = i - 1; j >= 0; j--) {
            if (list.get(i) < list.get(j)) {
                if (list.get(j) < tmp || tmp == -1) {
                    tmp = list.get(j);
                }
            }
        }
        newList.add(tmp);
    }
    list = newList;
}

更新:我忘了提到新值应该大于我们改变的元素。

3 个答案:

答案 0 :(得分:1)

你的方法目前是O(n ^ 2),其中n是列表的大小,因为嵌套循环的构造方式。

您不需要内部循环:您已经在要添加到列表中的下一个值上有一个上限,即新列表中的上一个值。如果输入列表中相应的前一个元素较小,则下一个元素将仅较小。所以只需取两个数字中较小的一个。

List<Integer> newList = new ArrayList<>();
if (list.size() > 0) { newList.add(-1); }
if (list.size() > 1) { newList.add(list.get(0)); }
for (int i = 2; i < list.size(); i++) {
  newList.add(Math.min(list.get(i-1), newList.get(i-1)));
}

答案 1 :(得分:0)

public static void main(String[] args) {
    int[] values = {10,3,5,7,9,2,2,14,-5,7,9,3};

    if ( values.length == 0 ) { return; }

    int minValue = values[0];
    int temp;
    values[0] = -1;

    for(int i=1; i<values.length; i++) {
        temp = values[i];
        values[i] = minValue;
        if ( temp < minValue ) {
            minValue = temp;
        }
    }

}

您可以记住当前项目之前的最小值,并在找到新项目时替换它。这个在O(N)中运行,不需要额外的内存。

答案 2 :(得分:0)

感谢cpp初学者的建议!树集和天花板方法使它工作:

public static void main(String[] args) throws InterruptedException {
    ArrayList<Integer> list = new ArrayList<>();
    Scanner scanner = new Scanner(System.in);
    int nElements = scanner.nextInt();
    for (int i = 0; i < nElements; i++) {
        list.add(scanner.nextInt());
    }
    ArrayList<Integer> newList = new ArrayList<>();
    TreeSet<Integer> set = new TreeSet<>();
    for (Integer aList : list) {
        Integer tmp = set.ceiling(aList + 1);
        if (tmp == null) {
            newList.add(-1);
        } else {
            newList.add(tmp);
        }
        set.add(aList);
    }
    list = newList;
}

谢谢大家!