[LeetCode]347. 前 K 个高频元素

news/2024/9/15 21:31:53/

题目

347.K 个高频元素
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。示例 1:输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:输入: nums = [1], k = 1
输出: [1]提示:1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。

方法1:HashMap+桶排

public int[] topKFrequent(int[] nums, int k) {//k:nums的每一个数,v:nums中每一个数出现的次数Map<Integer, Integer> freqMap = new HashMap<>();for (int x : nums) {freqMap.put(x, freqMap.getOrDefault(x, 0) + 1);}//bucket[freq]出现的次数,哪些数出现了freq次List<Integer>[] bucket = new List[nums.length + 1];for (int x : freqMap.keySet()) {int freq = freqMap.get(x);if (bucket[freq] == null) bucket[freq] = new ArrayList<>();bucket[freq].add(x);}List<Integer> res = new ArrayList<>();//从高到低freq开始收集resfor (int i = bucket.length - 1; i >= 0; --i) {if (bucket[i] != null) {for (int j = 0; j < bucket[i].size() && res.size() < k; j++) {res.add(bucket[i].get(j));}}}int[] ans = new int[res.size()];for (int i = 0; i < res.size(); i++) ans[i] = res.get(i);return ans;
}

方法2:HashMap+大根堆

 public int[] topKFrequent(int[] nums, int k) {//k:nums的每一个数,v:nums中每一个数出现的次数Map<Integer, Integer> freqMap = new HashMap<>();for (int x : nums) {freqMap.put(x, freqMap.getOrDefault(x, 0) + 1);}//做一个大根堆PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>((o1, o2) -> o2.getValue() - o1.getValue());for (Map.Entry<Integer, Integer> e : freqMap.entrySet()) {pq.offer(e);}List<Integer> res = new ArrayList<>();while (res.size() < k) {res.add(pq.poll().getKey());}int[] ans = new int[res.size()];for (int i = 0; i < res.size(); i++) ans[i] = res.get(i);return ans;}

方法3:HashMap+TreeMap

        public int[] topKFrequent(int[] nums, int k) {//k:nums的每一个数,v:nums中每一个数出现的次数Map<Integer, Integer> freqMap = new HashMap<>();for (int x : nums) {freqMap.put(x, freqMap.getOrDefault(x, 0) + 1);}TreeMap<Integer, List<Integer>> treeMap = new TreeMap<>();for (int x : freqMap.keySet()) {int freq = freqMap.get(x);treeMap.putIfAbsent(freq, new ArrayList<>());treeMap.get(freq).add(x);}List<Integer> res = new ArrayList<>();while (res.size() < k) {Map.Entry<Integer, List<Integer>> e = treeMap.pollLastEntry();res.addAll(e.getValue());}int[] ans = new int[res.size()];for (int i = 0; i < res.size(); i++) ans[i] = res.get(i);return ans;}

方法4:快速排序

public int[] topKFrequent(int[] nums, int k) {//k: 元素num v:出现的频次Map<Integer, Integer> map = new HashMap<>();for (int x : nums) map.put(x, map.getOrDefault(x, 0) + 1);List<int[]> freqList = new ArrayList<>();for (Map.Entry<Integer, Integer> e : map.entrySet()) {int num = e.getKey(), freq = e.getValue();freqList.add(new int[]{num, freq});}int[] res = new int[k];quickSort(freqList, 0, freqList.size() - 1, res, 0, k);return res;}/*** @param freqList 频次的list [0]为num [1]为freq* @param start    list的开始位置* @param end      list的结束位置* @param res      结果数组* @param resIndex 结果数组的当前待添加的下标索引* @param k        k*/
private void quickSort(List<int[]> freqList, int start, int end,int[] res, int resIndex, int k) {int pivotIndex = (int) (Math.random() * (end - start + 1)) + start;//随机选择哨兵Collections.swap(freqList, start, pivotIndex);//交换哨兵与start的位置int pivotFreq = freqList.get(start)[1];//当前的频次int index = start;for (int i = start + 1; i <= end; i++) {if (freqList.get(i)[1] >= pivotFreq) {//将频次高的放在左侧,频次低的放在右侧Collections.swap(freqList, index + 1, i);index++;}}Collections.swap(freqList, start, index);//将哨兵的位置放置在正确的位置if (index - start >= k) {//[start...index]段的元素比k多,需要在[start...index]段继续缩小范围quickSort(freqList, start, index - 1, res, resIndex, k);} else {for (int i = start; i <= index; i++) {//左侧部分即[start...index]都是需要的,开始收集res[resIndex++] = freqList.get(i)[0];}if (index - start + 1 < k) { // 当pivot和起点间的个数小于k时,则从pivot到end再继续找剩下的前(k - (pivot - start + 1))大的元素quickSort(freqList, index + 1, end, res, resIndex, k - (index - start + 1));}}}

http://www.ppmy.cn/news/551950.html

相关文章

LeetCode_每日一题347

文章目录 一、题目二、题解 一、题目 前 K 个高频元素 给定一个整数数组 nums 和一个整数 k &#xff0c;请返回其中出现频率前 k 高的元素。可以按 任意顺序 返回答案。 二、题解 var topKFrequent function(nums,k) {let o {}let num []for (let i 0; i < nums.len…

[day13]力扣239347

239: 滑动窗口最大值 设计一个单调队列&#xff0c; push规则:如果push的元素value大于入口元素的数值&#xff0c;那么就将队列入口的元素弹出&#xff0c;直到push元素的数值小于等于队列入口元素的数值为止。 pop规则&#xff1a;如果push的元素value大于入口元素的数值&…

leetcode周赛347前三题题解

1.移除字符串中的尾随零 题目描述 给你一个用字符串表示的正整数 num &#xff0c;请你以字符串形式返回不含尾随零的整数 num 。 示例 1&#xff1a; 输入&#xff1a;num "51230100" 输出&#xff1a;"512301" 解释&#xff1a;整数 "51230100…

LeetCode:347. 前 K 个高频元素

347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: [1]提示&#xff1a; 1 < nums.lengt…

374

我们正在玩一个猜数字游戏。 游戏规则如下&#xff1a; 我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。 每次你猜错了&#xff0c;我会告诉你这个数字是大了还是小了。 你调用一个预先定义好的接口 guess(int num)&#xff0c;它会返回 3 个可能的结果&#xff08;…

374a

#include<stdio.h> #include<math.h> #define inf 0x3fffffff int i,j,n,m,a,b; int max(int a,int b) {return a>b?a:b; } int min(int a,int b) {return a<b?a:b; } int dfs(int x,int y) {int dx,dy;if(ix&&jy)return 0;if(ia>n&&i-…

LeetCode 1374 - 1377

生成每种字符都是奇数个的字符串 假设 n 5&#xff0c;返回长度为 5 的字符串&#xff0c;保证返回的每个字符都出现奇数次&#xff0c;返回 5 个 a 即可或者返回 abcde 也可以 n 4&#xff0c;返回 aaab n 是奇数&#xff0c;返回 n 个 a n 是偶数&#xff0c;返回 n - 1…

Leetcode150, 239, 347

Leetcode 150 题目&#xff1a;逆波兰表达式 学习资料&#xff1a;代码随想录 初始思路 模拟计算过程&#xff0c;遇到数字放入栈中&#xff0c;当遇到运算符时&#xff0c;将栈顶前两个出栈并计算&#xff0c;然后将结果进栈 学习后 可以利用eval函数更简便的写法f 可以将表…

Leetcode Stackqueue 239 347

Leetcode 239 整体思想&#xff1a;用一个deque维护滑动窗口中的最大值 滑动窗口移动时&#xff0c;要删除掉最前面的数&#xff0c;并加入一个新的数&#xff0c;当新加入数的前面有小于这个数的值时&#xff0c;要把前面的数都pop掉&#xff0c;直到遇到最大值 deque: 是一个…

343

class Program{static void Main(string[] args){Primes primesFrom2To1000 new Primes(2, 1000);foreach (long i in primesFrom2To1000)Console.Write("{0} ", i);Console.ReadKey();}}

leetcood_347 C语言

题目描述&#xff1a;给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按任意顺序 返回答案。 示例 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 输入: nums [1], k 1 输出: [1] 提示 1 < nums.length < 105 k 的取值范…

第 347 场周赛

A 移除字符串中的尾随零 模拟 class Solution { public:string removeTrailingZeros(string num) {while(num.back()0)num.pop_back();return num;} };B 对角线上不同值的数量差 还是模拟… class Solution { public:vector<vector<int>> differenceOfDistinc…

算法day 13|239,347

今日内容&#xff1a; 239. 滑动窗口最大值 347.前 K 个高频元素 总结 239. 滑动窗口最大值 &#xff08;一刷至少需要理解思路&#xff09; class Myqueue(object):def __init__(self):self.queue deque()#保留队列最大的元素在队列里面&#xff0c;其他都pop掉def push(sel…

【C++核心】函数的应用和提高详解

一. 函数 1.1 概述 作用&#xff1a; 将一段经常使用的代码封装起来&#xff0c;减少重复代码。一个较大的程序&#xff0c;一般分为若干个程序块&#xff0c;每个模块实现特定的功能。 1.2 函数的定义 函数的定义一般主要有5个步骤&#xff1a; 1、返回值类型 2、函数名 3…

从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文

1 中断处理程序的基本要求 当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是中断执行完毕后要恢复到原来执行的程序,除了时间流逝外,原来运行的程序应该毫无感知。 具体到Armv…

【工具】Spring 历史官方文档理解(持续更新)

文章目录 [1] Spring Framework 5.2.24CoreAOP 概念AspectJoin pointAdvicePointcutIntroductionTarget objectAOP proxyWeaving Spring AOPAspectJ官方 demo 学习 Pointcut 表达式官方 demo 学习 Advice 声明官方 demo 学习 Introductions &#xff08;接口拓展&#xff09;AO…

5.2.3目录与文件之权限意义

现在我们知道了Linux系统内文件的三种身份&#xff08;拥有者、群组与其他人&#xff09;&#xff0c;知道每种身份都有三种权限&#xff08;rwx&#xff09;&#xff0c; 已知道能够使用chown, chgrp, chmod去修改这些权限与属性&#xff0c;当然&#xff0c;利用ls -l去观察文…

C语言倒计时器

今天用这几天所学知识自己编写一个简易计时器&#xff08;因为过于简单&#xff0c;所以不过多解释&#xff09; #include<stdio.h> #include<Windows.h>//编写一个倒计时器void main() {system("title 倒计时器");//设置标题system("mode con col…

51单片机实现倒计时,按键控制倒计时

基于AT89C52的答辩倒计时。四个按键分别控制倒计时开始&#xff0c;暂停&#xff0c;时间加和减。剩下30S时蜂鸣器响&#xff0c;倒计时结束蜂鸣器响。 #include <REGX52.H>unsigned char min1; unsigned char sec00; sbit KEY1P3^1; sbit KEY2P3^0; sbit KEY3P3^2; sbit…

单片机课设-60秒倒计时器

proteus单片机实现60秒倒计时器 项目要实现的60s秒表倒计时器&#xff0c;用 AT89C51单片机的定时 / 计数器 T0 产生一秒的定时时间&#xff0c;实现 59 到 0秒的循环显示的功能。具体要求&#xff1a; 1&#xff09;按下启动按键后&#xff0c;倒计时器开始工作&#xff0c;从…