题目
题目链接:
https://www.nowcoder.com/practice/fd711bdfa0e840b381d7e1b82183b3ee
核心
哈希,优先级队列
Java代码
java
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* return topK string
* @param strings string字符串一维数组 strings
* @param k int整型 the k
* @return string字符串二维数组
*/
public String[][] topKstrings (String[] strings, int k) {
//哈希 ,优先级队列
Map<String, Integer> smap = new HashMap<>();
for (String s : strings) {
if (!smap.containsKey(s)) {
smap.put(s, 0);
}
smap.put(s, smap.get(s) + 1);
}
PriorityQueue<Integer> pq1 = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
Map<Integer, PriorityQueue<String>> pqm = new HashMap<>();
Set<Integer> unique = new HashSet<>();
for (String s : smap.keySet()) {
int cnt = smap.get(s);
if (!unique.contains(cnt)) {
unique.add(cnt);
pq1.add(cnt);
pqm.put(cnt, new PriorityQueue<>());
}
pqm.get(cnt).add(s);
}
String[][] ans = new String[k][2];
int prevcnt = pq1.poll();
PriorityQueue<String> prevpq = pqm.get(prevcnt);
int idx = 0;
while (idx < k) {
while (idx < k && prevpq.size() > 0) {
String cur = prevpq.poll();
ans[idx][0] = cur;
ans[idx][1] = String.valueOf(prevcnt);
idx++;
}
if (idx == k) break;
prevcnt = pq1.poll();
prevpq = pqm.get(prevcnt);
}
return ans;
}
}
Go代码
go
package main
import (
"sort"
"strconv"
"strings"
)
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* return topK string
* @param strings string字符串一维数组 strings
* @param k int整型 the k
* @return string字符串二维数组
*/
func topKstrings(strings []string, k int) [][]string {
//哈希,优先级队列
smap := map[string]int{}
for _, s := range strings {
_, ok := smap[s]
if !ok {
smap[s] = 0
}
smap[s] = smap[s] + 1
}
times := []int{}
pqm := map[int]*PQAsc{}
unique := map[int]bool{}
for k, v := range smap {
_, ok := unique[v]
if !ok {
times = append(times, v)
pqm[v] = &PQAsc{Arr: make([]string, 10), Size: 0}
unique[v] = true
}
pqm[v].add(k) //k是字符串
}
ans := make([][]string, k)
sort.Ints(times)
idx := 0
for i := len(times) - 1; i >= 0; i-- {
curcnt := times[i]
pq := pqm[curcnt]
for idx < k && pq.Size > 0 {
ans[idx] = make([]string, 2)
ans[idx][0] = pq.remove()
ans[idx][1] = strconv.Itoa(curcnt)
idx++
}
}
return ans
}
// 上升堆 下标0也就是堆顶元素最小
type PQAsc struct {
Arr []string
Size int
}
// 扩容代码
func (pq *PQAsc) ensurecap(cap int) {
oldsize := len(pq.Arr)
if oldsize >= cap {
return
}
newsize := oldsize + oldsize>>1
newarr := make([]string, newsize)
for i := 0; i < oldsize; i++ {
newarr[i] = pq.Arr[i]
}
pq.Arr = newarr
}
func (pq *PQAsc) add(s string) {
pq.ensurecap(pq.Size + 1)
pq.Arr[pq.Size] = s
pq.shiftup(pq.Size)
pq.Size++
}
// 上滤
func (pq *PQAsc) shiftup(idx int) {
base := pq.Arr[idx]
for idx > 0 {
pid := (idx - 1) >> 1
parent := pq.Arr[pid]
/*
如果字符串相等(s1 == s2),则返回0
如果字符串1大于字符串2(s1> s2),则返回1。
如果字符串1小于字符串2,则返回-1
*/
if strings.Compare(base, parent) >= 0 {
break
}
pq.Arr[idx] = parent
idx = pid
}
pq.Arr[idx] = base
}
func (pq *PQAsc) remove() string {
ans := pq.Arr[0]
pq.Arr[0] = pq.Arr[pq.Size-1]
pq.Size--
pq.shiftdown(0)
return ans
}
// 下钻
func (pq *PQAsc) shiftdown(idx int) {
half := pq.Size >> 1
base := pq.Arr[idx]
for idx < half {
childidx := idx<<1 + 1
right := childidx + 1
child := pq.Arr[childidx]
if right < pq.Size && strings.Compare(child, pq.Arr[right]) >= 0 {
childidx = right
child = pq.Arr[right]
}
if strings.Compare(base, child) <= 0 {
break
}
pq.Arr[idx] = child
idx = childidx
}
pq.Arr[idx] = base
}