leetcode的Hot100系列--347. 前 K 个高频元素--hash表+直接选择排序
这个看着应该是使用堆排序,但我图了一个简单,所以就简单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表+直接选择排序的更多相关文章
- Java实现 LeetCode 347 前 K 个高频元素
347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...
- 力扣 - 347. 前 K 个高频元素
目录 题目 思路1(哈希表与排序) 代码 复杂度分析 思路2(建堆) 代码 复杂度分析 题目 347. 前 K 个高频元素 思路1(哈希表与排序) 先用哈希表记录所有的值出现的次数 然后将按照出现的次 ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- [LeetCode]347. 前 K 个高频元素(堆)
题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1 ...
- Leetcode 347.前K个高频元素 By Python
给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...
- leetcode.排序.347前k个高频元素-Java
1. 具体题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...
- leetcode 347. 前 K 个高频元素
问题描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...
- 347. 前K个高频元素
题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = ...
- 力扣347——前 K 个高频元素
这道题主要涉及的是对数据结构里哈希表.小顶堆的理解,优化时可以参考一些排序方法. 原题 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2, ...
随机推荐
- pipelinewise 学习一 docker方式安装
pipelinewise 没有提供基于pip 包的模式进行安装,而且推荐使用docker 以及源码的方式 以下是一个使用docker运行的方式 安装 git clone https://githu ...
- 洛谷p2370yyy2015c01的U盘题解
没什么特殊的想法 就是看自己很久没有更新关于题解类的文章了而已 (其实这是我好久之前做的, 只是把它从洛谷博客搬到了这里而已) 题目 首先分析题目要二分 他长成这个亚子太二分了 所以就要二分 最好是先 ...
- Nuxt + Vue 全家桶
引子 情由无中有,一旦有了,便万劫不复 简介 “简单却不失优雅,小巧而不乏大匠”. Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建 ...
- java 中类初始化,构造方法,静态成员变量,静态块的加载顺序
1.编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型.格式检查与编译成字节码文件,而加载是指java *的过程,将.class文件加载到内 ...
- shell脚本获取传入参数的个数
ts.sh #!/bin/bash echo $# 输出 [root@redhat6 ~]# ./ts.sh para1 [root@redhat6 ~]# ./ts.sh para1 para2 [ ...
- 使用apt-mirror搭建debian镜像源
debian官方提供了脚本ftpsync来搭建源镜像,而 apt-mirror 是一个更简单便捷的源镜像搭建工具. 安装 apt-mirror sudo apt-get install apt-mir ...
- spring-boot 知识集锦
1.spring-boot项目在外部tomcat环境下部署 https://blog.csdn.net/james_wade63/article/details/51009423 https://bl ...
- mysql 添加时间自动添加更新时间自动更新
在数据库使用中经常使用到时间字段.常用的有创建时间和更新时间.然而在使用中想要创建时间在创建的时候自动设置为当前时间,更新时间在更新时自动更新为当前时间. 创建表 stu CREATE TABLE ` ...
- linux命令详解之du命令
du命令概述du命令作用是估计文件系统的磁盘已使用量,常用于查看文件或目录所占磁盘容量.du命令与df命令不同,df命令是统计磁盘使用情况,详见linux命令详解之df命令.du命令会直接到文件系统内 ...
- 2的幂和按位与&——效率
以前学生时代,只是完成功能就行,进入公司之后,由于产品的特殊性,需要非常考虑效率,发现有以下几个策略(该文不定时更新): hash%length==hash&(length-1)的前提是len ...