解法一
利用字典统计次数 并排序 然后输出结果
字典统计:统计出每个元素的次数,大家千万注意到一旦涉及到关于次数的问题,一般都是用字典或者哈希表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个}}}
}