Leetcode 215&347&973 最大堆排序

Leetcode 28 数组中的K个最大元素


首先是最简单的纯堆排序:Leetcode 28
思想就是先全部堆排序,然后最后输出第K个大就可以。其实在排序的时候可以再简化一点,不需要全部排序,但是我为了图简单,就全部排序了==

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int n=nums.length-1;
        for(int i=(n-1)/2;i>=0;i--)
        {
            heapjust(nums,i,n);
        }
        for(int i=n;i>0;i--)
        {
            int temp=nums[0];
            nums[0]=nums[i];
            nums[i]=temp;
            heapjust(nums,0,i-1);
        }
        
        return nums[n-k+1];
    }
    public void heapjust(int[]nums,int parent,int n)
    {
        int temp=nums[parent];
        for(int i=2*parent+1;i<=n;i=i*2+1)
        {
            if(i<n&&nums[i]<nums[i+1]) i++;
            if(temp>=nums[i]) break;
            nums[parent]=nums[i];
            parent=i;
        }
        nums[parent]=temp;
    }    
}

接下来两大题我都用了key-value的思想。347题参考[leetcode]堆排序 求前k大的数。然后直到那时候,我才新认识了一种数据结构PriorityQueue,该结构直接实现最小堆排序。

Leetcode 347 前K个高频元素

class Solution {
    class keyvalue
    {
        Integer key;
        Integer value;
        public keyvalue(Integer key,Integer value)
        {
            this.key=key;
            this.value=value;
        }
    }
    public List<Integer> topKFrequent(int[] nums, int k) {
        Map<Integer,Integer>map=new HashMap<>();
        for(int i=0;i<nums.length;i++)//保存次数
        {
            if(map.containsKey(nums[i]))
            {
                map.put(nums[i],map.get(nums[i])+1);
            }
            else
            {
                map.put(nums[i],1);
            }
        }
        //定义一个priorityqueue
        Queue<keyvalue> queue=new PriorityQueue<keyvalue>(k,new Comparator<keyvalue>(){
            public int compare(keyvalue v1,keyvalue v2)
            {
                return v1.value-v2.value;
            }
        });
        Iterator iter=map.entrySet().iterator();
        int count=0;
        while(iter.hasNext())
        {
            Map.Entry entry=(Map.Entry)iter.next();
            keyvalue temp=new keyvalue((Integer)entry.getKey(),(Integer)entry.getValue());
            if(count<k)
            {
                queue.add(temp);
            }
            else if(temp.value>queue.peek().value)
            {
                queue.poll();
                queue.add(temp);
            }
            count++;              
        }
        List<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<k;i++)
        {
            list.add(0,queue.poll().key);
        }
        return list;
        
    }        
}

Leetcode 973 最接近原点的K个点


上面一道题用到了HashMap,这道题是我自己写的,因为还没有完全理解Map的思想,所有没有用到(现在还在思考这道题和347的区别在哪…)我同上一道题一样,定义了一个新的类,用keyvaule存储index和距离值。然后用PriorotyQueue排序。

class Solution {
    class keyvalue
    {
        Integer key;
        Integer value;
        public keyvalue(Integer key,Integer value)
        {
            this.key=key;
            this.value=value;
        }
    }
    public int[][] kClosest(int[][] points, int K) {
        int count=0;
        Queue<keyvalue>queue=new PriorityQueue<>(K,new Comparator<keyvalue>(){
            public int compare(keyvalue v1,keyvalue v2)
            {
                return v1.value-v2.value;
            }
        });
        for(int i=0;i<points.length;i++)
        {
            keyvalue temp=new keyvalue(i,points[i][0]*points[i][0]+points[i][1]*points[i][1]);
            if(count<K)
            {
                queue.add(temp);
                
            }
            else
            {
                keyvalue top=queue.peek();
                if(top.value<points[i][0]*points[i][0]+points[i][1]*points[i][1])
                {
                    queue.poll();
                    queue.add(temp);
                }
            }
        }
        int [][]result=new int[K][2];
        for(int i=0;i<K;i++)
        {
            keyvalue temp=queue.poll();
            result[i][0]=points[temp.key][0];
            result[i][1]=points[temp.key][1];
        }
                                                 
         return result;                                        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值