这个看着应该是使用堆排序,但我图了一个简单,所以就简单hash表加选择排序来做了。

使用结构体:

typedef struct node
{
struct node *pNext;
int value; // 数值
int frequency; // 频率
}NODE_S;

思路:

hash表用来存储每个值对应的频率,每读到一个数字,对应的频率就加1。

然后从表中再把这些数据读取出来。

先创建两个长度为k的数组,一个用来记录频率,一个用来记录对应的数值。

读取数据的时候,使用频率做排序,在排序的时候,也要对应的交换数值的数组。



/**
* Note: The returned array must be malloced, assume caller calls free().
*/ #define HASH_LEN 10 typedef struct node
{
struct node *pNext;
int value;
int frequency;
}NODE_S; NODE_S *get_node(NODE_S **pstHead, int num) // 获取num对应的节点
{
int n;
NODE_S *pstTemp;
if (num<0)
n = -num;
else
n = num;
pstTemp = pstHead[n%HASH_LEN]; while(NULL != pstTemp)
{
if (num == pstTemp->value)
return pstTemp;
else
pstTemp = pstTemp->pNext;
}
return pstTemp;
} void add_node(NODE_S **pstHashHead, int num) // 添加一个num的节点
{
NODE_S *pstTemp = NULL;
NODE_S *pstNode = NULL;
int i, n; if (num<0) // 这里是防止给的num是负数
n = -num;
else
n = num; pstTemp = get_node(pstHashHead, num);
if (NULL == pstTemp)
{
pstTemp = (NODE_S *)calloc(1, sizeof(NODE_S));
if (NULL == pstTemp) return;
pstTemp->value = num;
pstTemp->frequency = 1;
pstNode = pstHashHead[n%HASH_LEN];
if (NULL == pstNode)
pstHashHead[n%HASH_LEN] = pstTemp; // 说明是第一个节点
else
{
while (NULL != pstNode->pNext) // 往后面继续挂链表
{
pstNode = pstNode->pNext;
}
pstNode->pNext = pstTemp;
}
}
else
{
(pstTemp->frequency) ++; // 已经有该节点,则直接频率加1
}
return;
} void swap(int *frequency, int *value, int i, int k) // 交换频率的时候,也要交换对应的数值
{
int temp = frequency[i];
frequency[i] = frequency[k];
frequency[k] = temp;
temp = value[i];
value[i] = value[k];
value[k] = temp;
return;
} void selectSort(int *frequency, int *value, int len) // 选择排序
{
for(int i=0;i<len-1;i++)
{
int min = frequency[len-1-i];
int local = len-1-i;
for(int j=0;j<len-1-i;j++)
{
if(min > frequency[j])
{
min = frequency[j];
local = j;
}
} if(local != (len-1-i))
swap(frequency, value, local, len-1-i);
}
} int* topKFrequent(int* nums, int numsSize, int k, int* returnSize){
NODE_S *pstHashHeadValue[HASH_LEN] = {0};
NODE_S *pstTemp = NULL;
int *pTmp, i;
int *piFrequency = NULL, *piValue = NULL; for (i=0; i<numsSize; i++) // 把所有元素都插入到hash表中
{
add_node(pstHashHeadValue, nums[i]);
} // 这里生成两个数组,一个频率数组,一个数值数组,频率数组用来排序, 数值数组用来返回
piFrequency = (int *)calloc(k, sizeof(int));
if (NULL == piFrequency) return NULL;
piValue = (int *)calloc(k, sizeof(int));
if (NULL == piValue) return NULL; int count = 0;
for (i=0; i<HASH_LEN; i++)
{
if (NULL != pstHashHeadValue[i])
{
NODE_S *pstTemp = pstHashHeadValue[i];
while (NULL != pstTemp)
{
if (count<k)
{
piFrequency[count] = pstTemp->frequency;
piValue[count] = pstTemp->value;
count ++;
if (count == k)
selectSort(piFrequency, piValue, k); // 把数组填满之后,先做一次排序
}
else
{
if (pstTemp->frequency > piFrequency[k-1]) // 只有当该频率大于当前存储最小频率的时候,才需要进行重新排序
{
piFrequency[k-1] = pstTemp->frequency;
piValue[k-1] = pstTemp->value;
selectSort(piFrequency, piValue, k);
}
}
pstTemp = pstTemp->pNext;
}
}
} *returnSize = k;
return piValue; }

leetcode的Hot100系列--347. 前 K 个高频元素--hash表+直接选择排序的更多相关文章

  1. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  2. 力扣 - 347. 前 K 个高频元素

    目录 题目 思路1(哈希表与排序) 代码 复杂度分析 思路2(建堆) 代码 复杂度分析 题目 347. 前 K 个高频元素 思路1(哈希表与排序) 先用哈希表记录所有的值出现的次数 然后将按照出现的次 ...

  3. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  4. [LeetCode]347. 前 K 个高频元素(堆)

    题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1 ...

  5. Leetcode 347.前K个高频元素 By Python

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...

  6. leetcode.排序.347前k个高频元素-Java

    1. 具体题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...

  7. leetcode 347. 前 K 个高频元素

    问题描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素.   示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...

  8. 347. 前K个高频元素

    题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = ...

  9. 力扣347——前 K 个高频元素

    这道题主要涉及的是对数据结构里哈希表.小顶堆的理解,优化时可以参考一些排序方法. 原题 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2, ...

随机推荐

  1. A1102 | 反转二叉树

    #include <stdio.h> #include <memory.h> #include <math.h> #include <string> # ...

  2. MySQL性能优化 分区

    简述 分区是指根据一定的规则,数据库将表分解为多个更小的,更容易管理的部分,就访问数据库而言,逻辑上只有一张表或一个索引,但实际上这张表可能又多个物理分区共同构成,每一个分区都是一个独立的对象,可以独 ...

  3. ELK实时日志分析平台环境部署,以及可视化展示

    ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件.新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent) ...

  4. Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面

    Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面 viewModelWithLikeData.getLikeNumber().observe(this, ne ...

  5. [技术博客]windows中使用docker技术

    背景 我们的工程使用了一个叫做termux的安卓上的linux终端,这个终端在所有的软件包里硬编码了软件的运行路径(/data/data/com.termux/..),由于安卓系统的权限设计,我们名为 ...

  6. 拷贝Maven依赖jar包到指定目录

    一.导出到默认目录 targed/dependency 从Maven项目中导出项目依赖的jar包:进入工程pom.xml 所在的目录下,执行如下命令: 1 mvn dependency:copy-de ...

  7. Java编程思想之七复用类

    复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须做更多的事情. 使用类而不破坏程序代码: 在新类中产生现有对象.由于新的类是由现有 ...

  8. Python导入 from lxml import etree 导入不了

    问题在学爬虫,Python 版本是2.7,安装的lxml包是4.3的,在 from lxml import etree 时发现一直报错,网上查询,原来是Python版本和lxml包版本不一致导致的. ...

  9. FilelistCreator --- 导出文件列表神器 及其他好用工具

    https://www.sttmedia.com/ Standard Software WordCreator: Creates readable words, sentences or texts ...

  10. vue重置表单数据

    Object.assign(this.$data, this.$options.data()) // 全部重置 Object.assign(this.$data.form, this.$options ...