簡體   English   中英

給定一個列表和一個 x 的值,將其拆分,使所有小於 x 的項目排在大於或等於 x 的項目之前

[英]Given a list and a value of x, split it such that all items less than x came before items greater than or equal to x

我有個問題。 有沒有更有效的方法來解決這個問題? 我做了如下所示,但我創建了 3 個新列表。

public List<Integer> divideListByX1(List<Integer> list, int x) {
    List<Integer> beforeX = new ArrayList<>();
    List<Integer> afterX = new ArrayList<>();
    List<Integer> all = new ArrayList<>();
    for (Integer integer : list) {
        boolean b = (integer < x) ? beforeX.add(integer) : afterX.add(integer);
    }
    all.addAll(beforeX);
    all.addAll(afterX);
    return all;
}

謝謝你的幫助

這可以使用 Quicksort 的 Pivot 操作在線性時間內就地完成:

public static void pivot(List<Integer> list, int pivot) {
    int left = 0;
    int right = list.size() - 1;

    while (left < right) {
        while (left < list.size() && list.get(left) < pivot) {
            left++;
        }
        while (right >= 0 && list.get(right) >= pivot) {
            right--;
        }
        if (left < right)
            Collections.swap(list, left++, right--);
    }
}

下面的方法效率稍微高一點,因為它將數字直接添加到一個 go 的結果列表中,而不是使用中間列表:

public static List<Integer> divideListByX1(List<Integer> list, int x) {
    Integer[] result = new Integer[list.size()];
    int lowIndex = 0;
    int highIndex = result.length - 1;
    for (Integer n : list) {
        if (n < x)
            result[lowIndex++] = n;
        else
            result[highIndex--] = n;
    }
    return Arrays.asList(result);
}

這樣做的缺點是“高數字”部分不是輸入列表的原始順序,但我想這並不重要。

另外,這里有一種使用 Streams 的方法,但可能不會比您最初的嘗試更有效:

public List<Integer> divideListByX1(List<Integer> list, int x) {
    return list
        .stream()
        .collect(Collectors.partitioningBy(n -> n >= x))
        .values()
        .stream()
        .flatMap(List::stream)
        .toList();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM