数组中的第K个最大元素(经典题)
添加链接描述
思路:建一个大小为K的小根堆,那么最后的堆顶就是第K大的值
class Solution {
public int findKthLargest(int[] nums, int k) {
int[]heap=new int[k];
for (int i=0;i<nums.length;i++){
if (i<k){
heap[i]=nums[i];
if (i==k-1){
// 建堆:从第一个非叶子节点到堆顶节点进行调整,调整完就是一个初始的小根堆
for (int j=k/2-1;j>=0;j--){
heapSort(heap,j);
}
}
}else {
if (nums[i]>heap[0]){
//替换堆顶并重新调整
heap[0]=nums[i];
heapSort(heap, 0);
}
}
}
return heap[0];
}
private void heapSort(int[] heap, int j) {
int k=j*2+1;
while (k<heap.length){
if (k+1<heap.length && heap[k+1]<heap[k]){
k++;
}
if (heap[j]>heap[k]){
swap(heap,k,j);
j=k;
k=j*2+1;
}else {
break;
}
}
}
private void swap(int[] heap, int k, int j) {
int temp=heap[k];
heap[k]=heap[j];
heap[j]=temp;
}
}
c++:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n=nums.size();
vector<int>heap(k);
for(int i=0;i<n;i++){
if(i<k){
heap[i]=nums[i];
if(i==k-1){
for(int i=k/2-1;i>=0;i--){
heapSort(heap,i,k);
}
}
}else{
if(nums[i]>heap[0]){
heap[0]=nums[i];
heapSort(heap,0,k);
}
}
}
return heap[0];
}
void heapSort(vector<int>& heap,int i,int k){
int j=i*2+1;
while(j<k){
if(j+1<k && heap[j+1]<heap[j]){
j++;
}
if(heap[i]>heap[j]){
swap(heap[i],heap[j]);
i=j;
j=i*2+1;
}else{
break;
}
}
}
};
前 K 个高频元素
前 K 个高频元素
方法和上题一模一样,只是多用一个hashMap记录出现的次数
class Solution {
//<元素,元素出现的个数>
Map<Integer , Integer> map = new HashMap<>();
public int[] topKFrequent(int[] nums, int k) {
for(int i : nums){
map.put(i , map.getOrDefault(i,0) + 1);
}
//得到数组中的所有元素
Iterator it = map.keySet().iterator();
// 定义heap数组,下标从1开始
int[] heap = new int[k+1];
int i = 1;
while(it.hasNext()){
// 先初始化一个大小为k的堆,当堆中元素个数为k时,建立小根堆
if( i <= k){
heap[i] = (Integer)it.next();
if(i == k){
for(int j = k/2 ; j >= 1 ; j--){
heapSort(heap,j);
}
}
i++;
}else{ //小根堆建好后 ,对于每个新遍历的元素与堆顶比较,如果比堆顶大,替换堆顶,重新维持小根堆
int key = (Integer)it.next();
if(map.get(key) > map.get(heap[1])){
heap[1] = key;
heapSort(heap , 1);
}
}
}
// heap数组下标0没有使用,需要去掉
int[] ans=new int[k];
for(int j=1;j<=k;j++){
ans[j-1]=heap[j];
}
return ans;
}
//维持小根堆
//注意,堆中元素比较是比较它们出现的次数,即该元素在map中对应的value
public void heapSort(int[] heap , int i){
int j=i*2; // 0*2=0 所有下标要从1开始
while (j<heap.length){ // j+1比j小的话,就要把j+1换上去。
if(j+1<heap.length && map.get(heap[j+1])<map.get(heap[j])){
j++;
}
if(map.get(heap[i])>map.get(heap[j])){
int temp = heap[i];
heap[i]=heap[j];
heap[j]=temp;
i=j;
j=j*2;
}else {
break;
}
}
}
}