题面
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
输入:
"tree"
输出:
"eert"
解释:
'e’出现两次,'r’和’t’都只出现一次。
因此’e’必须出现在’r’和’t’之前。此外,"eetr"也是一个有效的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-characters-by-frequency
堆排序
- 实现go 堆的
heap.Interface
接口 - 自定义依据重复次数实现最大堆排序规则
import (
"bytes"
"container/heap"
"fmt"
)
type ByteSliceHeap [][]byte
var _ heap.Interface = (*ByteSliceHeap)(nil)
func (h ByteSliceHeap) Len() int { return len(h) }
func (h ByteSliceHeap) Less(i, j int) bool { return len(h[i]) > len(h[j]) }
func (h ByteSliceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *ByteSliceHeap) Push(x interface{}) {
*h = append(*h, x.([]byte))
}
func (h *ByteSliceHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func frequencySort(s string) string {
m := make(map[byte][]byte, 0)
for i := 0; i < len(s); i++ {
if _, ok := m[s[i]]; !ok {
m[s[i]] = []byte{s[i]}
} else {
m[s[i]] = append(m[s[i]], s[i])
}
}
h := &ByteSliceHeap{}
for _, v := range m {
heap.Push(h, v)
}
buf := &bytes.Buffer{}
for h.Len() > 0 {
buf.Write(heap.Pop(h).([]byte))
}
return buf.String()
}
哈希+切片插入
- 哈希计数
- 计数排序
- 字节重复
- 切片插入
func frequencySort(s string) string {
rs := []byte{}
m := make(map[byte]int,0)
for i:=0;i<len(s);i++ {
if _, ok := m[s[i]];!ok {
rs = append(rs, s[i])
}
m[s[i]]++
}
sort.Slice(rs,func(i, j int)bool{
return m[rs[i]] > m[rs[j]]
})
for i:=0;i<len(rs);i++ {
if cnt := m[rs[i]]-1;cnt > 0 {
rept := bytes.Repeat([]byte{rs[i]}, cnt)
rear := append([]byte{},rs[i:]...)
rs=append(rs[:i],rept...)
rs=append(rs,rear...)
i +=cnt
}
}
return string(rs)
}