关注公众号:云下凤澜 , 免费领取Java学习 面试资料
通用双解法:
1.快速排序:
步骤1:先选择一个基准点,然后从右指针R往左找第一个大于基准点的数,再从左指针L往右找第一个小于基准点的数,当L>=R时,将L指针指向基准点数值,这样基准点左侧就都是大于基准点的数,右侧为小于基准点的数。
步骤2:此时,如果寻找的第k大的数小于L那就证明第K大的数在L左边,所以再将L左侧数据重复步骤1。同理,如果寻找的第K大的数大于L那就证明第K大的数在L右边,所以再将L右边的数据重复步骤1.
步骤3:直到L==K的时候,就找到了第K大的数。
附上代码:
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public static int fastSortFind( int [] a, int left, int right, int k){ int i = left; int j = right; int target = a[left]; while (i < j){ while (i < j && a[j] <= target) j--; if (i < j){ a[i] = a[j]; i++; } while (i target) i++; if (i < j){ a[j] = a[i]; j--; } } a[i] = target; if (i == k){ return target; } else if (i > k){ return fastSortFind(a,left,i - 1 ,k); } else { return fastSortFind(a,i+ 1 ,right,k); } } |
2.利用最小堆的特征,数组arr,构建一个 数组arr前K个元素组成的最小堆,然后遍历arr的k 到 length-1的元素,将每一个元素与堆顶元素比较,如果大于堆顶元素就将其替换,并重新进行构建最小堆。
复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public static void buildMinHeap( int [] metaData){ if (metaData == null || metaData.length == 0 || metaData.length == 1 ){ return ; } for ( int i = (metaData.length/ 2 ) - 1 ;i>= 0 ;i--){ heapify(metaData,i,metaData.length); } } private static void heapify( int [] metaData, int i, int length) { if (metaData == null || metaData.length == 0 || metaData.length == 1 ){ return ; } int small = metaData[i]; for ( int k=( 2 *i)+ 1 ;k<length;k= 2 *k+ 1 ){ if (k+ 1 < length && metaData[k]>metaData[k+ 1 ]){ k++; } if (small > metaData[k]){ swap(metaData,i,k); i = k; } else { break ; } } } private static void swap( int [] metaData, int i, int k) { int temp = metaData[i]; metaData[i] = metaData[k]; metaData[k] = temp; } |