快速排序
用于求解kth Element问题,也就是第k个元素的问题。
堆
用于求解TopK Elements问题,也就是k个最小元素的问题。可以维护一个大小为k的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到k个最小的元素,因此当遍历到一个新元素时,需要知道这个新元素是否比堆中的最大元素要小,更小的话就把堆中最大元素去除,并把新元素添加到堆中。所以我们很容易得到最大元素并移除最大元素,大顶堆就能很好的满足这个需求。
1.Kth Element
Input: [3,2,1,5,6,4] and k = 2
Output: 5
题目描述:找到倒数第k个元素
排序:时间复杂度为O(NlogN),空间复杂度为O(1)
public int findKthLargest(int[] nums,int k){
Arrays.sort(nums);
return nums[nums.length-k];
}
堆:时间复杂度为O(NlogN),空间复杂度为O(k)
public int findkthLargest(int[] nums,int k){
PriorityQuene<Integer> pq=new priorityQuene<>();//小顶堆
for(int val:nums){
pq.add(val);
if(pq.size()>k)//维护堆大小为k
pq.poll();
}
return pq.peek();
快速选择:时间复杂度O(N),空间复杂度O(1)
public int findkthLargest(int[] nums,int k){
k=nums.length-k;
int l=0,h=nums.length-1;
while(l<h){
int j=partition(nums,l,h);
if(j==k){
break;
}else if(j<k){
l=j+1;
}else{
h=j-1;
}
}
return nums[k];
}
private int partition(int [] a,int l,int h){
int i=l,j=h+1;
while(true){
while(a[++i]<a[l]&&j<h);
while(a[--j]>a[l]&&j>l);
if(i>=j){
break;
}
swap(a,i,j);
return j;
}
private void swap(int[] a,int i,int j){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
桶排序
1.出现频率最高的K个元素
Given [1,1,1,2,2,3] and k = 2, return [1,2].
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第i个桶中存储的数出现的频率为i。
把数都放到桶之后,从后向前遍历桶,最先得到的k个数就是出现频率最多的k个数。
public List<Integer> topKFrequent(int[] nums,int k){
Map<Integer,Integer> frequencyForNum=new HashMap<>();
for(int num:nums){
frequencyForNum.put(num,frequencyForNum.getOrDefault(num,0)+1);
}
List<Integer>[] buckets=new ArraryList[nums.length+1];
for(int key:frequencyForNum.keySet()){
int frequency=frequencyForNum.get(key);
if(buckets[frequency]==null){
buckets[frequency]=new ArrayList<>();
}
buckets[frequency].add(key);
}
List<Integer>[] buckets=new ArrayList[nums.length+1];
for(int key:frequencyForNum.keySet()){
int frequency=frequencyForNum.get(key);
if(buckets[frequency]==null){
buckets[frequency]=new ArrayList<>();
}
buckets[frequency].add(key);
}
List<Integer> topK=new ArrayList<>();
for(int i=buckets.length-1;i>=0&&topK.size()<k;i--){
if(buckets[i]==null){
continue;
}
if(buckets[i].size()<=(k-topK.size())){
topK.addAll(buckets[i]);
}else{
topK.addAll(buckets[i].subList(0,k-topK.size()));
}
}
return topK;
}