zoukankan      html  css  js  c++  java
  • 最大的K个数

    建立最大的k个数,可以通过快速排序来实现,也可以通过堆排序来实现。我们来看堆排序的实现过程。

    其中,也是有两种思路:第一种思路是:把数组里的所有的数建堆(O(nlogn)),然后交换k次,通过堆排序实现。(klogn)

      时间复杂度是:O((n+k)logn) = O(nlogn)

    第二种思路是:先用前面的k个数来建最小堆,堆顶元素将会是这个堆里的最小值,然后从第K+1个数开始和堆顶元素进行比较,若此值比堆顶元素小,则这个数比大的至少有k个元素,这个值肯定不是最大的k个数;若此值比堆顶元素大,则这个数有可能是最大的k个数,调整这个堆即可。最后建立的堆就是所求的最大的k个数,并且堆顶元素就是最大的k个数中的最小值。

    时间复杂度是:(O(klogk)+O(n-k)logk) = O(nlogk)

    第二种思路的代码:

    public int[] heapSort(int[] array,int k){
            int length = array.length;
            for(int i=(k-2/2);i>=0;i--){  //先建立具有K个元素的大顶堆
                adjustHeap(array,i,k-1);
            }
            for(int i=k;i<array.length;i++){ //比较n-K次
                if(array[0]>array[i])
                {
                    swap(array,0,i);
                    adjustHeap(array,0,k-1);
                }
            }
            return array;
        }
        public void adjustHeap(int[] array,int m,int n){
            while(2*m+1<=n){
                int p = 2*m+1;
                if(p<n){
                    if(array[p]<array[p+1]){
                        p=p+1;
                    }
                }
                if(array[m]<array[p]){
                    swap(array,m,p);
                    m = p;
                }else{
                    break;
                }
                
            }
        }
        public void swap(int[] array,int p,int q){
            int temp = array[q];
            array[q] = array[p];
            array[p] = temp;
        }

     第一种思路:先把所有的数建堆,然后再交换。

    public static void main(String[] args){
    		int[] array = {1,2,3,4,5,6,7,8};
    		int[] result = new lianxi().heapSort(array,4);
    	}
    	public int[] heapSort(int[] array,int k){
    		int length = array.length;
    		for(int i=(length-2/2);i>=0;i--){
    			adjustHeap(array,i,length-1);
    		}
    		for(int i=0;i<k;i++){
    				swap(array,0,length-1-i);
    				adjustHeap(array,0,length-2-i); //此处为length-2-i,因为每次需要调整的堆的长度都减1
    				System.out.println(array[length-1-i]);
    		}
    		return array;
    	}
    	public void adjustHeap(int[] array,int m,int n){
    		while(2*m+1<=n){
    			int p = 2*m+1;
    			if(p<n){
    				if(array[p]>array[p+1]){
    					p=p+1;
    				}
    			}
    			if(array[m]>array[p]){
    				swap(array,m,p);
    				m = p;
    			}else{
    				break;
    			}
    			
    		}
    	}
    	public void swap(int[] array,int p,int q){
    		int temp = array[q];
    		array[q] = array[p];
    		array[p] = temp;
    	}
    

      在堆排序的基础上进行修改:

    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
            ArrayList<Integer> arrayList = new ArrayList<>();
            if(input == null || k<=0 || k>input.length) return arrayList;
            for(int i=0;i<input.length;i++){
                buildMinHeap(input,input.length-1-i);
                swap(input,0,input.length-1-i);
            }
            for(int i=0;i<k;i++){
                arrayList.add(input[i]);
            }
            return arrayList;
        }
        public void buildMinHeap(int[] input,int n){
               int i;
            if(n==input.length-1) i=(n-1)/2;
            else i=0;
            for(;i>=0;i--){
                int p = i;
                while(p*2+1<=n){
                    int q = 2*p+1;
                    if(q<n){
                        if(input[q]<input[q+1]){
                            q = q+1;
                        }
                    }
                    if(input[p]<input[q]){
                        int temp = input[q];
                        input[q] = input[p];
                        input[p] = temp;
                        p=q;
                    }else{
                        break;
                    }
                }
            }
        }
        public  void swap(int[] input,int i,int j){
            int temp = input[j];
            input[j] = input[i];
            input[i] = temp;
        }

    先构造一个k个元素的堆,然后再进行比较。

    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
            ArrayList<Integer> arrayList = new ArrayList<>();
            if(input == null || k<=0 || k>input.length) return arrayList;
            buildMaxHeap(input,k-1);
            for(int i=k;i<input.length;i++){
                if(input[i]<input[0]){
                    swap(input,0,i);
                    adjust(input,0,k-1);
                }
            }
            for(int i=0;i<k;i++){
                arrayList.add(input[i]);
            }
            return arrayList;
        }
        public void buildMaxHeap(int[] input,int n){
            for(int i= (n-1)/2;i>=0;i--){
                int p = i;
                while(p*2+1<=n){
                    int q = 2*p+1;
                    if(q<n){
                        if(input[q]<input[q+1]){
                            q = q+1;
                        }
                    }
                    if(input[p]<input[q]){
                        int temp = input[q];
                        input[q] = input[p];
                        input[p] = temp;
                        p=q;
                    }else{
                        break;
                    }
                }
            }
        }
        public void adjust(int[] input,int m,int n){
            while(2*m+1<=n){
                int q = 2*m+1;
                if(q<n){
                    if(input[q]<input[q+1]){
                        q = q+1;
                    }
                }
                if(input[m]<input[q]){
                    swap(input,m,q);
                    m = q;
                }else{
                    break;
                }
            }
        }
        public  void swap(int[] input,int i,int j){
            int temp = input[j];
            input[j] = input[i];
            input[i] = temp;
        }
  • 相关阅读:
    Python基础 2----Python 基础语法
    安卓开发35:一些安卓设计经验总结
    HDU 4707 Pet(DFS(深度优先搜索)+BFS(广度优先搜索))
    对象数组
    Mac与Window之间的共享文件
    实用数据结构总结之二叉树遍历
    csdn的登录框好难看
    图像切割性能评价
    基于Solr的HBase实时查询方案
    图片的缩放源码与使用
  • 原文地址:https://www.cnblogs.com/yingpu/p/5813263.html
Copyright © 2011-2022 走看看