推免机试练习2(排序)

快速排序
用于求解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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值