根据类似元素的出现次数对arraylist进行排序

时间:2017-10-01 02:14:41

标签: java list sorting

我有一个包含{2,2,1,1,1,5,4,4,4,4,4}的ArrayList,我想根据每个元素的出现次数对其进行排序。所以它会给{4,4,4,4,4,1,1,1,2,2,5}。我从哪里开始?

import java.util.*;

public class SortingL{

  public static void main(String[] args){

    ArrayList<Integer> list = new ArrayList<Integer>();

    Integer[] al = new Integer[] {2,2,1,1,1,5,4,4,4,4,4};
    list.addAll(Arrays.asList(al));

    sortL(list);

  }

  public static ArrayList<Integer> sortL(ArrayList<Integer> list){


    return list;
  }
}

3 个答案:

答案 0 :(得分:4)

一种解决方案是使用Collections#frequency

List<Integer> list = Arrays.asList(2, 2, 1, 1, 1, 5, 4, 4, 4, 4, 4);

list.sort(Comparator.comparing(i -> Collections.frequency(list, i)).reversed());

System.out.println(list);

这将输出预期结果:

  

[4,4,4,4,4,1,1,1,2,2,5]

答案 1 :(得分:2)

为获得最佳性能,请首先构建值Map以计算值。然后按计数排序,并重新构建数组。

效果是将合并出现相同次数的不同值。您可能希望指定二级订单,然后对它们进行一致排序。

示例:

public static void main(String[] args) {
    ArrayList<Integer> input = new ArrayList<>(Arrays.asList(2,2,1,1,1,5,4,4,4,4,4));
    ArrayList<Integer> sorted = sortL(input);
    System.out.println(sorted); // prints: [4, 4, 4, 4, 4, 1, 1, 1, 2, 2, 5]
}
public static <V extends Comparable<V>> ArrayList<V> sortL(List<V> input) {
    Map<V, ValueCount<V>> map = new HashMap<>();
    for (V value : input)
        map.computeIfAbsent(value, ValueCount<V>::new).count++;
    @SuppressWarnings("unchecked")
    ValueCount<V>[] arr = map.values().toArray(new ValueCount[map.size()]);
    Arrays.sort(arr);
    ArrayList<V> sorted = new ArrayList<>(input.size());
    for (ValueCount<V> vc : arr)
        for (int i = 0; i < vc.count; i++)
            sorted.add(vc.value);
    return sorted;
}
private static final class ValueCount<V extends Comparable<V>> implements Comparable<ValueCount<V>> {
    final V value;
    int count;
    ValueCount(V value) {
        this.value = value;
    }
    @Override
    public int compareTo(ValueCount<V> that) {
        int cmp = Integer.compare(that.count, this.count); // descending
        if (cmp == 0)
            cmp = that.value.compareTo(this.value); // descending
        return cmp;
    }
}

答案 2 :(得分:1)

你可以用O(N)来做(很少有内存空间的权衡。 )

  1. 列表项
  2. 创建一个hashmap
  3. 迭代输入元素并保持每个元素的计数 hashmap中的元素
  4. 现在按频率迭代Map的密钥和存储桶编号
  5. 现在以相反的顺序迭代存储桶
  6. 代码:

    public List<Integer> frequencyBasedSort(int[] nums, int k) {
        List<Integer>[] bucket = new List[nums.length + 1];
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int n : nums) {
            freqMap.put(n, freqMap.getOrDefault(n, 0) + 1);
        }
        for (int key : freqMap.keySet()) {
            int frequency = freqMap.get(key);
            if (bucket[frequency] == null) {
                bucket[frequency] = new ArrayList<>();
            }
            bucket[frequency].add(key);
        }
        List<Integer> res = new ArrayList<>();
        for (int i = bucket.length - 1; i >= 0; i--) {
            if (bucket[i] != null) {
                res.addAll(bucket[i]);
            }
        }
        return res;
    }