牛客NC97 字符串出现次数的TopK问题【中等 哈希+优先级队列 Java/Go】

题目

题目链接:

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
}
相关推荐
PAK向日葵3 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
地平线开发者6 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
地平线开发者6 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
星星火柴9367 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑8 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
C++、Java和Python的菜鸟9 小时前
第六章 统计初步
算法·机器学习·概率论
Cx330❀9 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
散11210 小时前
01数据结构-Prim算法
数据结构·算法·图论
起个昵称吧10 小时前
线程相关编程、线程间通信、互斥锁
linux·算法
myzzb10 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa