【题目】
给定一个无序的整型数组arr,找到其中最小的k个数
【要求】
如果数组arr的长度为N,排序之后自然可以得到最小的k个数,此时时间复杂度与排序的时间复杂度相同,均为O(NlogN),请实现时间复杂度为O(Nlogk)的方法
1 public int[] getMinKNums(int[] arr, int k) 2 { 3 if(k < 1 || k > arr.length) 4 { 5 return arr; 6 } 7 8 int[] kHeap = new int[k]; // 使用一个大根堆结构来保存最小的k个数 9 for(int i = 0; i < k; i++) 10 { 11 heapInsert(kHeap, arr[i], i); 12 } 13 for(int i = k; i < arr.length; i++) 14 { 15 if(arr[i] < kHeap[0]) 16 { 17 kHeap[0] = arr[i]; 18 heapify(kHeap, 0, k); 19 } 20 } 21 return kHeap; 22 } 23 24 public void heapInsert(int[] arr, int value, int index) 25 { 26 int parent = 0; 27 arr[index] = value; 28 while(index != 0) 29 { 30 parent = (index - 1) / 2; 31 if(arr[parent] < arr[index]) 32 { 33 swap(arr, parent, index); 34 index = parent; 35 } 36 else 37 { 38 break; 39 } 40 } 41 } 42 43 public void heapify(int[] arr, int index, int heapSize) 44 { 45 int left = index * 2 + 1; 46 int right = index * 2 + 2; 47 int largest = index; 48 while(left < heapSize) 49 { 50 if(arr[left] > arr[index]) 51 { 52 largest = left; 53 } 54 if(right < heapSize && arr[right] > arr[largest]) 55 { 56 largest = right; 57 } 58 if(largest != index) 59 { 60 swap(arr, index, largest); 61 } 62 else 63 { 64 break; 65 } 66 index = largest; 67 left = index * 2 + 1; 68 right = index * 2 + 2; 69 } 70 } 71 72 73 public void swap(int[] arr, int i, int j) 74 { 75 int temp = arr[i]; 76 arr[i] = arr[j]; 77 arr[j] = temp; 78 }
来源:左程云老师《程序员代码面试指南》