将元素插入按频率排序的数组中,然后再按频率对数组进行排序

时间:2017-09-11 19:30:12

标签: java arrays algorithm sorting

所以我被要求写一个O(n)函数insertRanked(int[] list, int item),将一个元素插入到按频率排序的数组中(我编写了一个布尔函数来检查int[] list是否已排序按频率)。将元素插入数组后,然后按频率再次对数组进行排序。

例如,insertRanked([65, 65, 65, 65, 1, 1, 1, 8, 8, 987, 987, 2, 2, 40], 2)应生成[65, 65, 65, 65, 1, 1, 1, 2, 2, 2, 8, 8, 987, 987, 40]

这可以在O(n)中做到吗?我曾考虑将元素及其计数存储到LinkedHashMap并使用Collections.sort(),但Collections.sort()的时间复杂度为O(n * log(n))。

2 个答案:

答案 0 :(得分:2)

启动你的一种方法可以基于计数。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeMap;

    public class SortCount {
        public static void main(String[] args) {
            int nums[] = {([65, 65, 65, 65, 1, 1, 1, 8, 8, 987, 987, 2, 2, 40};
            HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();

            for(int i = 0; i < nums.length; i++) {
                if(counts.containsKey(nums[
                    Integer c = counts.get(nums[i]) + 1;
                    counts.put(nums[i], c);
                }
                else {
                    counts.put(nums[i],1);
                }
            }

            ValueComparator<Integer,Integer> bvc = new ValueComparator<Integer,Integer>(counts);
            TreeMap<Integer,Integer> sortedMap = new TreeMap<Integer,Integer>(bvc);
            sortedMap.putAll(counts);

            ArrayList<Integer> output = new ArrayList<Integer>();
            for(Integer i : sortedMap.keySet()) {
                for(int c = 0; c < sortedMap.get(i); c++) {
                    output.add(i);
                }
            }

            System.out.println(output.toString());
        }
    }

//Which uses a Comparator class to compare the values in a Map:



 import java.util.Comparator;
    import java.util.Map;

    public class ValueComparator<T1,T2 extends Comparable<T2>> implements Comparator<T1> {
        Map<T1,T2> base;
        public ValueComparator(Map<T1,T2> base) {
            this.base = base;
        }

        @Override
        public int compare(T1 k1, T1 k2) {
            T2 val1 = base.get(k1);
            T2 val2 = base.get(k2);

            return val1.compareTo(val2);
        }
    }

答案 1 :(得分:2)

假设数组已经按频率排序,当然可以在O(n)中进行排序。遍历数组一次以找出所讨论元素的频率变化(在您的示例中,2从2的频率变为3)。在第二次迭代中,将数字逐个插入到新数组中,直到达到具有插入元素的目标频率的最后一个元素。插入目标元素适当的次数并继续插入其余元素,跳过目标元素。