347. 前 K 个高频元素

2019-07-22  本文已影响0人  最困惑的时候就是能成长的时候

347. 前 K 个高频元素

1.想法

利用Map存储每个数的频次,<key,value>-><num,frequency>,然后将数据读出,存储在两个int的数组里面,一个int[] tag代表了这个数字,然后int[] frequency代表了数字的频次,然后根据frequency调整tag,利用frequency建立大根堆或者小根堆,输出前k或者后k个数.
堆排序:https://www.jianshu.com/p/1977402d9277

2.代码

public List<Integer> topKFrequent(int[] nums, int k) {
        List<Integer> result = new ArrayList<>();
        Map<Integer,Integer> res = new HashMap<>();
        //先记录每个数字的频次
        for(int i=0;i<nums.length;i++){
            res.put(nums[i],res.getOrDefault(nums[i],0)+1);
        }
        int[] tags = new int[res.size()];
        int[] frequency = new int[res.size()];
        int i = 0;
        Iterator iterator = res.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry item = (Map.Entry) iterator.next();
            tags[i] = (int) item.getKey();
            frequency[i++] = (int) item.getValue();
        }
        builtMinHeap(tags,frequency,k);
        for(int index = tags.length-1;index>tags.length-1-k;index--){
            result.add(tags[index]);
        }
        return result;
    }
    //建立小根堆,当后k个数排序完成时,算法结束
    private void builtMinHeap(int[] tags, int[] frequency, int k) {
        int count = 0;
        for(int i=tags.length/2-1;i>-1;i--){
            dealSnap(tags,frequency,i,tags.length);
        }
        while(count<k){
            swap(tags,frequency,tags.length-1-count,0);
            dealSnap(tags,frequency,0,tags.length-1-count);
            count++;
        }
    }
   //调整过程
    private void dealSnap(int[] tags, int[] frequency, int start, int end) {
       if(2*start+1>=end){
           return;
       }else if(2*(start+1)>=end){
           if(frequency[2*start+1]>=end){
               swap(tags,frequency,2*start+1,start);
           }
       }else{
           if(frequency[start]>=frequency[2*start+1]&&frequency[start]>=frequency[2*(start+1)]){
               return;
               //左子树最大,交换后去排列左边
           }else if(frequency[2*start+1]>=frequency[start]&&frequency[2*start+1]>=frequency[2*(start+1)]){
               swap(tags,frequency,2*start+1,start);
               dealSnap(tags,frequency,2*start+1,end);
               //右子树最大,交换后去排列右边
           }else{
               swap(tags,frequency,2*(start+1),start);
               dealSnap(tags,frequency,2*(start+1),end);
           }
       }
    }
  //交换过程
    private void swap(int[] tags, int[] frequency, int i, int j) {
        int tempTag = tags[i];
        int tempFraquency = frequency[i];
        tags[i] = tags[j];
        frequency[i] = frequency[j];
        tags[j] = tempTag;
        frequency[j] = tempFraquency;
    }
上一篇下一篇

猜你喜欢

热点阅读