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

devtools/2024/10/18 16:54:10/

题目

在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/fd711bdfa0e840b381d7e1b82183b3ee

核心

	哈希,优先级队列

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>() {@Overridepublic 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代码

package mainimport ("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 := 0for 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  []stringSize int
}// 扩容代码
func (pq *PQAsc) ensurecap(cap int) {oldsize := len(pq.Arr)if oldsize >= cap {return}newsize := oldsize + oldsize>>1newarr := 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] = spq.shiftup(pq.Size)pq.Size++
}// 上滤
func (pq *PQAsc) shiftup(idx int) {base := pq.Arr[idx]for idx > 0 {pid := (idx - 1) >> 1parent := pq.Arr[pid]/*如果字符串相等(s1 == s2),则返回0如果字符串1大于字符串2(s1> s2),则返回1。如果字符串1小于字符串2,则返回-1*/if strings.Compare(base, parent) >= 0 {break}pq.Arr[idx] = parentidx = 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 >> 1base := pq.Arr[idx]for idx < half {childidx := idx<<1 + 1right := childidx + 1child := pq.Arr[childidx]if right < pq.Size && strings.Compare(child, pq.Arr[right]) >= 0 {childidx = rightchild = pq.Arr[right]}if strings.Compare(base, child) <= 0 {break}pq.Arr[idx] = childidx = childidx}pq.Arr[idx] = base
}

http://www.ppmy.cn/devtools/38216.html

相关文章

计算方法实验2(补充):列主元消元法解线性方程组

C源代码 #include<bits/stdc.h> using namespace std;// 列主元消去法求解线性方程组 vector<long double> Column_Elimination(vector<vector<long double>> A, vector<long double> b);int main() {vector<vector<long double>> …

Ansible——playbook编写

一、简介 1.什么是playbook Ansible Playbook 是设定自动化任务的一种蓝图&#xff0c;可在无需人工干预或有限干预的前提下执行复杂的 IT 操作。Ansible Playbook 对一组或一类共同构成 Ansible 清单的主机执行。 Ansible Playbook 本质上是一些框架&#xff0c;是一些预先编…

VxTerm使用教程:连接SSH服务端设备,什么是SSH

一、什么是SSH&#xff1f; <摘自百度> 安全外壳协议 SSH&#xff0c;即安全外壳协议&#xff08;Secure Shell&#xff09;&#xff0c;是一种网络协议&#xff0c;用于在计算机网络上提供安全的远程登录和命令执行功能。 SSH通过加密通信通道来保护数据传输&#xff0c…

STM32中的Systick的使用

SysTick&#xff0c;全称System Tick Timer&#xff0c;是Cortex-M microcontrollers内核中提供的一个简单而有效的系统定时器&#xff0c;设计用来给操作系统提供时间基准&#xff0c;或用于生成周期性的中断。STM32系列微控制器&#xff0c;作为基于ARM Cortex-M内核的设备&a…

Java | Leetcode Java题解之第66题加一

题目&#xff1a; 题解&#xff1a; class Solution {public int[] plusOne(int[] digits) {int n digits.length;for (int i n - 1; i > 0; --i) {if (digits[i] ! 9) {digits[i];for (int j i 1; j < n; j) {digits[j] 0;}return digits;}}// digits 中所有的元素…

Docker 中快速构建 Redis Cluster 集群

Docker 中快速构建 Redis Cluster 集群 目录 前言环境准备 所需软件配置网络 构建 Redis Cluster 镜像 创建自定义 Dockerfile构建镜像 启动 Redis 节点容器 启动命令 配置 Redis Cluster 集群 创建 Redis 集群验证集群状态 总结 前言 Redis 是一个高性能的键值对数据库&am…

顺序栈的操作

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;既然选择了远方&#xff0c;当不负青春…

力扣数据库题库学习(5.4日)--1667. 修复表中的名字

1667. 修复表中的名字 问题链接 解题思路 使用 SUBSTRING() 函数获取每个名字的第一个字符和剩余字符。 使用 UPPER() 函数将第一个字符转换为大写。 使用 LOWER() 函数将剩余字符转换为小写。 使用 CONCAT() 函数将第一个字符和剩余字符组合成名字。 最后按照 user_id 对结…