总结
一般有三种解法,排序、堆、快排思想
1.寻找第K大
描述: 给定一个整数数组a,同时给定它的大小n和要找的K(1<=K<=n),请返回第K大的数(包括重复的元素,不用去重),保证答案存在。
import java.util.*;
public class Solution {
public int findKth(int[] a, int n, int K) {
// write code here
return quickSort(a,0,n-1,K);
}
public int quickSort(int[] a,int left,int right,int K){
//从大到小快排
int i=left;
int j=right;
int pos=a[left];
while(i<j){
while(i<j&&a[j]<=pos){
j--;
}
a[i]=a[j];
while(i<j&&a[i]>=pos){
i++;
}
a[j]=a[i];
}
a[i]=pos;
if(K==i+1){
return a[i];
}else if(K<i+1){
return quickSort(a,left,i-1,K);
}else{
return quickSort(a,i+1,right,K);
}
}
}
2.最小的K个数
描述: 给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> res=new ArrayList<>();
if(k==0||k>input.length){
return res;
}else if(k==input.length){
for(int i=0;i<input.length;i++){
res.add(input[i]);
}
return res;
}
partitionArray(input,0,input.length-1,k);
for(int i=0;i<input.length&&i<k;i++){
res.add(input[i]);
}
return res;
}
public void partitionArray(int[] input,int left,int right,int k){
int m=quickSort(input,left,right);
if(k==m){
//前k个数即为所求
return;
}else if(k>m){
partitionArray(input,m+1,right,k);
}else if(k<m){
partitionArray(input,left,m-1,k);
}
}
public int quickSort(int[] input,int left,int right){
//从小到达快排
int pos=input[left];
while(left<right){
while(left<right&&input[right]>=pos){
right--;
}
input[left]=input[right];
while(left<right&&input[left]<=pos){
left++;
}
input[right]=input[left];
}
input[left]=pos;
return left;
}
}
3.出现次数的TopK问题
描述: 请返回出现次数前k名的字符串和对应的次数。
返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。
import java.util.*;
public class Solution {
/**
* return topK string
* @param strings string字符串一维数组 strings
* @param k int整型 the k
* @return string字符串二维数组
*/
public String[][] topKstrings (String[] strings, int k) {
// write code here
Map<String, Integer> map = new HashMap<>();
for(String s : strings){
map.put(s, map.getOrDefault(s,0)+1);
}
//默认为最小堆,定义Node排序规则
PriorityQueue<Node> minHeap = new PriorityQueue<>(k);
for(Map.Entry<String,Integer> entrySet : map.entrySet()){
Node node=new Node(entrySet.getKey(),entrySet.getValue());
if(minHeap.size()<k){
minHeap.offer(node);
}else{
if(minHeap.peek().compareTo(node)<0){
minHeap.poll();
minHeap.offer(node);
}
}
}
String[][] res=new String[k][2];
for(int i=k-1;i>=0;i--){
Node node=minHeap.poll();
res[i][0]=node.name;
res[i][1]=String.valueOf(node.count);
}
return res;
}
}
class Node implements Comparable<Node>{
String name;
int count;
public Node(String name, int count){
this.name=name;
this.count=count;
}
@Override
public int compareTo(Node node){
//count大,则交换
if(this.count>node.count){
return 1;
}else if(this.count<node.count){
return -1;
}else{
//字典序小,则交换到前面
return node.name.compareTo(this.name);
}
}
}