我有一个包含{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;
}
}
答案 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)来做(很少有内存空间的权衡。 )
代码:
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;
}