2017-10-01 6 views
1

私は{2,2,1,1,1,5,4,4,4,4,4}を含むArrayListを持っており、各要素の出現回数に応じてソートしたい。だからそれは{4,4,4,4,4,1,1,1,2,2,5}を与えるでしょう。どこから始めますか?同様の要素の発生数に応じてarraylistを並べ替える

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; 
    } 
} 
+1

は、サードパーティのライブラリ公正なゲームはありますか? –

+0

@LouisWassermanいいえ、私はできるだけ簡単にしたい –

+0

入力が '1,2,1,2'の場合、両方の値は同じ時間数になるので、4つの値はすべて同じ「重み」を持つので、a安定したソート(これはJavaのソートです)では、4つの値は変更されません。それはあなたが欲しいものですか? – Andreas

答えて

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]

+2

解決策が速い必要がある場合は、Jigar Joshiの答えを使用してください。私は 'O(n^2)'で完了するようです。 –

1

O(N)で行うことができます(メモリスペースのトレードオフはほとんどありません) )

  1. リスト項目
  2. 今すぐ周波数
  3. によって地図のキーとバケット番号を反復あなたの入力要素をハッシュマップ
  4. 反復を作成し、ハッシュマップ
  5. に各 要素の数を維持しますバケットを逆順に反復する

コード:

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; 
} 
+0

私はすでに4を指摘しています。あなたはポイント5についてもっと説明できますか? –

+1

@ JohnP。たとえば、あなたの最大値は '6'です(この例では)。 6から0にループし、要素をhashmapで検索します。 hashmapから取得した値がゼロでない場合は、それを印刷します。 –

+1

修正:ハッシュマップから取得された値が「ヌル」でない場合は、 –

2

最高のパフォーマンスを得るには、最初に値のカウントに値のMapを作成します。それをcountでソートし、配列を再構築します。

同じ回数で発生する異なる値が統合されるという効果があります。あなたはおそらく二次注文を指定したいと思うでしょうし、一貫して並べ替えられています。

例:

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; 
    } 
} 
関連する問題