How to arrange an array in decreasing order of frequency of each number?

前端 未结 7 524
一整个雨季
一整个雨季 2021-01-03 04:23

Input : {5, 13, 6, 5, 13, 7, 8, 6, 5}

Output : {5, 5, 5, 13, 13, 6, 6, 7, 8}

The question is to arrange the numbers in the array in

相关标签:
7条回答
  • 2021-01-03 04:42

    I can think of two solutions:

    Make a first pass to count frequencies and store the first index and then sort according to that

    This is simple to implement, uses linear (O(N)) additional memory in the worst case and takes O(N log N) time.

    Do everything in one pass with some sort of priority queue, where the "priority" is the frequency count (changing as you pass through the input), and the index of the first occurrence to break ties

    This does everything in a single pass, but I can't think of any advantage over the other solution. It still requires O(N) additional memory, and will also take O(N log N) time. Also, it requires a more complex data structure.

    0 讨论(0)
  • 2021-01-03 04:45

    You can probably do it in one pass with a bubble sort type algorithm where you keep a note of the count of the previous value and swap bunches of numbers when you find more of another number.

    But - as a first step you should do a 2pass solution, with a std::map/pair to store number or if you are told the range of values in advance use a simple array.

    0 讨论(0)
  • 2021-01-03 04:52

    I guess I'd do it like this:

    Use a key-value data structure where the number itself is the key and the occurrence count and first occurrence index are the value.

    Now traverse all numbers. If the number is not yet known (in the data structure), add it, remembering the current index as well as 1 as count. Otherwise, increment the count.

    Now sort the data structure contents by the occurrence count (decreasing) and the occurrence index (increasing), and output the result (repeating the number using the occurrence count).

    Processing space used <= N, time used depending on data structure and dictionary would probably be about O(N log N)

    0 讨论(0)
  • 2021-01-03 04:55

    Sort the array, and in your sort function for x, y: sort by count(x) vs. count(y). If they are the same, sort by index(x) vs. index(y)

    In python:

    input = [5, 13, 6, 5, 13, 7, 8, 6, 5]
    orig = list(input)
    
    def cmp(x, y):
        if (orig.count(y) - orig.count(x) != 0):
            return orig.count(y) - orig.count(x)
        return orig.index(x) - orig.index(y)   
    
    input.sort(cmp) 
    print input
    

    To make it more efficient, precalculate counts and indexes before sorting the array.

    0 讨论(0)
  • 2021-01-03 04:57
    private static void sortByFrequency(int[] a)
    {
        Map<Integer, Element> map = new HashMap<Integer, Element>();
        for(int i=0; i<a.length; i++)
        {
            if(map.get(a[i]) == null)
            {
                map.put(a[i], new Element(i));
            }
            else
            {
                Element e = map.get(a[i]);
                e.frequency++;
            }
        }
    
        Set<Integer> set = map.keySet();
        TreeSet<Element> treeSet = new TreeSet<Element>();
        for(int i : set)
        {
            treeSet.add(map.get(i));
        }
    
        for(Element e : treeSet)
        {
            for(int i=0; i<e.frequency;i++)
            {
                System.out.println(a[e.index]);
            }
        }
    }
    
    private static class Element implements Comparable<Element>
    {
        private final int index;
        private int frequency;
    
        Element(int index)
        {
            this.index = index;
            this.frequency = 1;
        }
    
        @Override
        public int compareTo(Element o)
        {
            int k = o.frequency - this.frequency;
            if(k != 0) return k;
            else
            {
                return this.index - o.index;
            }
        }
    }
    
    public static void main(String[] args)
    {
        int[] a = {5, 13, 6, 5, 13, 7, 8, 6, 5};
        sortByFrequency(a);
    }
    
    0 讨论(0)
  • 2021-01-03 05:00

    In Python2.7 or Python3.1

    >>> from collections import Counter
    >>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
    >>> c=Counter(L)
    >>> def keyfunc(x):
    ...     return (-c.get(x),L.index(x))
    ... 
    >>> sorted(L,key=keyfunc)
    [5, 5, 5, 13, 13, 6, 6, 7, 8]
    

    In Python2.6

    >>> from collections import defaultdict
    >>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
    >>> c=defaultdict(int)
    >>> for x in L:
    ...     c[x]+=1
    ... 
    >>> def keyfunc(x):
    ...     return (-c.get(x),L.index(x))
    ... 
    >>> sorted(L,key=keyfunc)
    [5, 5, 5, 13, 13, 6, 6, 7, 8]
    

    Here is a version that doesn't use any library functions (weird constraint)

    >>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
    >>> c={}
    >>> for x in L:
    ...     c[x]=c.setdefault(x,0)+1
    ... 
    >>> def keyfunc(x):
    ...     return (-c.get(x),L.index(x))
    ... 
    >>> sorted(L,key=keyfunc)
    [5, 5, 5, 13, 13, 6, 6, 7, 8]
    

    In each case, keyfunc is used to control the ordering of the sort

    keyfunc(5) returns (-3,0)
    keyfunc(6) returns (-2,2)
    keyfunc(7) returns (-1,5)
    keyfunc(8) returns (-1,6)
    keyfunc(13) returns (-2,1)
    

    The list items are sorted according to the return value of keyfunc

    0 讨论(0)
提交回复
热议问题