Sort Characters By Frequency

May 22, 2020

Introduction

Given a string, sort it in decreasing order based on the frequency of characters.

Example 1:

Input: “tree”

Output: “eert”

Explanation: ‘e’ appears twice while ‘r’ and ’t’ both appear once. So ‘e’ must appear before both ‘r’ and ’t’. Therefore “eetr” is also a valid answer. Example 2:

Input: “cccaaa”

Output: “cccaaa”

Explanation: Both ‘c’ and ‘a’ appear three times, so “aaaccc” is also a valid answer. Note that “cacaca” is incorrect, as the same characters must be together. Example 3:

Input: “Aabb”

Output: “bbAa”

Explanation: “bbaA” is also a valid answer, but “Aabb” is incorrect. Note that ‘A’ and ‘a’ are treated as two different characters.

Solution

Let’s calculate frequency table and sort it with payload (character) and format output.

type IntPriority []int

func (p IntPriority) Len() int           { return len(p)/2 }
func (p IntPriority) Less(i, j int) bool { return p[i*2] > p[j*2] }
func (p IntPriority) Swap(i, j int)      { p[i*2], p[j*2], p[i*2+1], p[j*2+1] = p[j*2], p[i*2], p[j*2+1], p[i*2+1] }


func frequencySort(s string) string {
    freq := make([]int, 512)
    for i := 0; i <= 255; i++ {
        freq[i*2+1] = i  // payload is letter
    }
    for _, ch := range []byte(s) {
        freq[int(ch)*2]++
    }
    sort.Sort(IntPriority(freq))
    out := make([]byte, len(s))
    for i, k := 0, 0; i < 512 && freq[i] > 0; i += 2 {
        for j := 0; j < freq[i]; j++ {
            out[k] = byte(freq[i+1])
            k++
        }
    }
    return string(out)
}

Performance of this solution:

Runtime: 0 ms, faster than 100.00% of Go online submissions for Sort Characters By Frequency.
Memory Usage: 5 MB, less than 100.00% of Go online submissions for Sort Characters By Frequency.

comments powered by Disqus

Do you want to know me more private?→Click!