|
| 1 | +package Others; |
| 2 | + |
| 3 | +import java.util.Arrays; |
| 4 | + |
| 5 | +/** |
| 6 | + * BFPRT algorithm. |
| 7 | + */ |
| 8 | +public class BFPRT { |
| 9 | + |
| 10 | + public static int[] getMinKNumsByBFPRT(int[] arr, int k) { |
| 11 | + if (k < 1 || k > arr.length) { |
| 12 | + return null; |
| 13 | + } |
| 14 | + int minKth = getMinKthByBFPRT(arr, k); |
| 15 | + int[] res = new int[k]; |
| 16 | + int index = 0; |
| 17 | + for (int i = 0; i < arr.length; i++) { |
| 18 | + if (arr[i] < minKth) { |
| 19 | + res[index++] = arr[i]; |
| 20 | + } |
| 21 | + } |
| 22 | + for (; index != res.length; index++) { |
| 23 | + res[index] = minKth; |
| 24 | + } |
| 25 | + return res; |
| 26 | + } |
| 27 | + |
| 28 | + public static int getMinKthByBFPRT(int[] arr, int k) { |
| 29 | + int[] copyArr = copyArray(arr); |
| 30 | + return bfprt(copyArr, 0, copyArr.length - 1, k - 1); |
| 31 | + } |
| 32 | + |
| 33 | + public static int[] copyArray(int[]arr) { |
| 34 | + int[] copyArr = new int[arr.length]; |
| 35 | + for(int i = 0; i < arr.length; i++) { |
| 36 | + copyArr[i] = arr[i]; |
| 37 | + } |
| 38 | + return copyArr; |
| 39 | + } |
| 40 | + |
| 41 | + public static int bfprt(int[] arr, int begin, int end, int i) { |
| 42 | + if (begin == end) { |
| 43 | + return arr[begin]; |
| 44 | + } |
| 45 | + int pivot = medianOfMedians(arr, begin, end); |
| 46 | + int[] pivotRange = partition(arr, begin, end, pivot); |
| 47 | + if (i >= pivotRange[0] && i <= pivotRange[1]) { |
| 48 | + return arr[i]; |
| 49 | + } else if (i < pivotRange[0]) { |
| 50 | + return bfprt(arr, begin, pivotRange[0] - 1, i); |
| 51 | + } else { |
| 52 | + return bfprt(arr, pivotRange[1] + 1, end, i); |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + /** |
| 57 | + * wikipedia: https://en.wikipedia.org/wiki/Median_of_medians . |
| 58 | + * @param arr an array. |
| 59 | + * @param begin begin num. |
| 60 | + * @param end end num. |
| 61 | + * @return median of medians. |
| 62 | + */ |
| 63 | + public static int medianOfMedians(int[] arr, int begin, int end) { |
| 64 | + int num = end - begin + 1; |
| 65 | + int offset = num % 5 == 0 ? 0 : 1; |
| 66 | + int[] mArr = new int[num / 5 + offset]; |
| 67 | + for (int i = 0;i < mArr.length;i++) { |
| 68 | + mArr[i] = getMedian(arr, begin + i * 5, Math.min(end, begin + i * 5 + 4)); |
| 69 | + } |
| 70 | + return bfprt(mArr, 0, mArr.length - 1, mArr.length / 2); |
| 71 | + } |
| 72 | + |
| 73 | + public static void swap(int[]arr, int i, int j) { |
| 74 | + int swap = arr[i]; |
| 75 | + arr[i] = arr[j]; |
| 76 | + arr[j] = swap; |
| 77 | + } |
| 78 | + |
| 79 | + public static int[] partition(int[] arr,int begin,int end,int num) |
| 80 | + { |
| 81 | + int small=begin-1; |
| 82 | + int cur=begin; |
| 83 | + int big=end+1; |
| 84 | + while(cur!=big) |
| 85 | + { |
| 86 | + if (arr[cur]<num) |
| 87 | + { |
| 88 | + swap(arr,++small,cur++); |
| 89 | + }else if (arr[cur]>num) |
| 90 | + { |
| 91 | + swap(arr,--big,cur); |
| 92 | + } else { |
| 93 | + cur++; |
| 94 | + } |
| 95 | + } |
| 96 | + int[] pivotRange=new int[2]; |
| 97 | + pivotRange[0]=small+1; |
| 98 | + pivotRange[1]=big-1; |
| 99 | + return pivotRange; |
| 100 | + } |
| 101 | + |
| 102 | + public static int getMedian(int[] arr, int begin, int end) { |
| 103 | + insertionSort(arr, begin, end); |
| 104 | + int sum = begin + end; |
| 105 | + int mid = sum / 2 + (sum % 2); |
| 106 | + return arr[mid]; |
| 107 | + } |
| 108 | + |
| 109 | + public static void insertionSort(int[] arr, int begin, int end) { |
| 110 | + if (arr == null || arr.length < 2) { |
| 111 | + return; |
| 112 | + } |
| 113 | + for (int i = begin + 1;i != end + 1;i++) { |
| 114 | + for (int j = i;j != begin;j--) { |
| 115 | + if (arr[j - 1] > arr[j]) { |
| 116 | + swap(arr, j - 1, j); |
| 117 | + } else { |
| 118 | + break; |
| 119 | + } |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + public static void main(String[] args) { |
| 125 | + int[] arr = { 11, 9, 1, 3, 9, 2, 2, 5, 6, 5, 3, 5, 9, 7, 2, 5, 5, 1, 9 }; |
| 126 | + int[] minK = getMinKNumsByBFPRT(arr,5); |
| 127 | + System.out.println(Arrays.toString(minK)); |
| 128 | + } |
| 129 | +} |
0 commit comments