这个看着应该是使用堆排序,但我图了一个简单,所以就简单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. pipelinewise 学习一 docker方式安装

    pipelinewise 没有提供基于pip 包的模式进行安装,而且推荐使用docker 以及源码的方式 以下是一个使用docker运行的方式 安装   git clone https://githu ...

  2. 洛谷p2370yyy2015c01的U盘题解

    没什么特殊的想法 就是看自己很久没有更新关于题解类的文章了而已 (其实这是我好久之前做的, 只是把它从洛谷博客搬到了这里而已) 题目 首先分析题目要二分 他长成这个亚子太二分了 所以就要二分 最好是先 ...

  3. Nuxt + Vue 全家桶

    引子 情由无中有,一旦有了,便万劫不复 简介 “简单却不失优雅,小巧而不乏大匠”. Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建 ...

  4. java 中类初始化,构造方法,静态成员变量,静态块的加载顺序

    1.编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型.格式检查与编译成字节码文件,而加载是指java *的过程,将.class文件加载到内 ...

  5. shell脚本获取传入参数的个数

    ts.sh #!/bin/bash echo $# 输出 [root@redhat6 ~]# ./ts.sh para1 [root@redhat6 ~]# ./ts.sh para1 para2 [ ...

  6. 使用apt-mirror搭建debian镜像源

    debian官方提供了脚本ftpsync来搭建源镜像,而 apt-mirror 是一个更简单便捷的源镜像搭建工具. 安装 apt-mirror sudo apt-get install apt-mir ...

  7. spring-boot 知识集锦

    1.spring-boot项目在外部tomcat环境下部署 https://blog.csdn.net/james_wade63/article/details/51009423 https://bl ...

  8. mysql 添加时间自动添加更新时间自动更新

    在数据库使用中经常使用到时间字段.常用的有创建时间和更新时间.然而在使用中想要创建时间在创建的时候自动设置为当前时间,更新时间在更新时自动更新为当前时间. 创建表 stu CREATE TABLE ` ...

  9. linux命令详解之du命令

    du命令概述du命令作用是估计文件系统的磁盘已使用量,常用于查看文件或目录所占磁盘容量.du命令与df命令不同,df命令是统计磁盘使用情况,详见linux命令详解之df命令.du命令会直接到文件系统内 ...

  10. 2的幂和按位与&——效率

    以前学生时代,只是完成功能就行,进入公司之后,由于产品的特殊性,需要非常考虑效率,发现有以下几个策略(该文不定时更新): hash%length==hash&(length-1)的前提是len ...