解法一
利用字典统计次数 并排序 然后输出结果
字典统计:统计出每个元素的次数,大家千万注意到一旦涉及到关于次数的问题,一般都是用字典或者哈希表c#中一般就直接用字典更方便
Dictionary<int,int> mydic = new Dictionary<int,int>();
for (int i = 0; i < nums.Length; i++)
{
if (mydic.ContainsKey(nums[i]))
{
mydic[nums[i]]++;
}
else
{
mydic[nums[i]] = 1;
}
}
排序输出结果:
var list = mydic.Keys.ToList();
list.Sort((a, b) => mydic[b].CompareTo(mydic[a]));//自定义排序算法 降序排序
return list.Take(k).ToArray();//取前K个
解法二:
利用字典计数+小根堆
先将每个元素出现的频数记录在字典中,然后通过不断的往小根堆中添加,直到添加至最后一个元素频数,每次维护K个元素在小根堆中,即小根堆,保留的就是最大的K个元素的频数,最后直接出队列就行
核心算法,如果你的语言不自带小根堆,需自己手动实现。
var heap = new PriorityQueue<int,int>();
foreach (var pair in mydic)
{
heap.Enqueue(pair.Key, pair.Value);
if(heap.Count>k) heap.Dequeue();
}
int[] result = new int[k];
for (int i = 0; i < k; i++)
{
result[i] = heap.Dequeue();
}
return result;
方法三
利用字典计数加桶排序
思路:字典记录下元素频数后,维护一个数组,数组中的每个元素为一个列表,每个元素索引记录出现的频数,元素列表记录出现过这么多频数的原数组中的元素(即字典的Key)
①首先建立一个桶数组
var bucket = new List<int>[nums.Length + 1];
foreach (var num in mydic)
{
int count = num.Value;
if (bucket[count]==null) bucket[count] = new List<int>();
bucket[count].Add(num.Key);
}
②你现在维护的这个桶数组,从尾往头看,每个索引对应的 就是频数最大的元素列表,如果当前频数对应的没有列表(即为空),就依次向前走,直到你找到K个元素之后,就直接退出
List<int> result = new List<int>();
for (int i = bucket.Length - 1; i > 0 && result.Count < k; i--)
{
if (bucket[i] != null)
{
foreach (var item in bucket[i])
{
result.Add(item);
if(result.Count==k)
break;
}
}
}
return result.ToArray();
附:整个实现代码
namespace _347_前K个高频元素
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
public class Solution
{
public int[] TopKFrequent(int[] nums, int k)
{
Dictionary<int,int> mydic = new Dictionary<int,int>();
for (int i = 0; i < nums.Length; i++)
{
if (mydic.ContainsKey(nums[i]))
{
mydic[nums[i]]++;
}
else
{
mydic[nums[i]] = 1;
}
}
//方法三
//var bucket = new List<int>[nums.Length + 1];
//foreach (var num in mydic)
//{
// int count = num.Value;
// if (bucket[count]==null) bucket[count] = new List<int>();
// bucket[count].Add(num.Key);
//}
//List<int> result = new List<int>();
//for (int i = bucket.Length - 1; i > 0 && result.Count < k; i--)
//{
// if (bucket[i] != null)
// {
// foreach (var item in bucket[i])
// {
// result.Add(item);
// if(result.Count==k)
// break;
// }
// }
//}
//return result.ToArray();
//方法二
//var heap = new PriorityQueue<int,int>();
//foreach (var pair in mydic)
//{
// heap.Enqueue(pair.Key, pair.Value);
// if(heap.Count>k) heap.Dequeue();
//}
//int[] result = new int[k];
//for (int i = 0; i < k; i++)
//{
// result[i] = heap.Dequeue();
//}
//return result;
//方法一
var list = mydic.Keys.ToList();
list.Sort((a, b) => mydic[b].CompareTo(mydic[a]));//自定义排序算法 降序排序
return list.Take(k).ToArray();//取前K个
}
}
}
}