思路跟精华题解里面两个堆的一样,不过自己写了两个数组实现堆,写着写着写了好长🤣
因为数据分成两半,左半边是小一点的数,如果要取数字就要取最大的,所以是大顶堆。右半边是大一点的数,如果取数字就要取最小的,所以是小顶堆。
插入数字的时候,做了细致的分类处理,看了一下别的解答,我这个太复杂了hhh
public class Solution { private static int[] smallHalf = new int[501]; // 存小的一半数字,用大顶堆 private static int[] largeHalf = new int[501]; // 存大的一半数字,用小顶堆 // 如果偶数个数字,则各存一半,否则放在小数字数组 private static int lenSmall = 0; // 小数字部分有几个数 private static int lenLarge = 0; // 大数字部分有几个数 public void Insert(Integer num) { if (lenSmall == 0) { smallHalf[1] = num; lenSmall++; return; } else if (lenLarge == 0) { if (num >= smallHalf[1]) { largeHalf[1] = num; } else { largeHalf[1] = smallHalf[1]; smallHalf[1] = num; } lenLarge++; return; } else if (num < smallHalf[1]) { if (lenSmall == lenLarge) { lenSmall++; smallHalf[lenSmall] = num; swimSmall(lenSmall); return; } else { lenLarge++; largeHalf[lenLarge] = smallHalf[1]; swimLarge(lenLarge); smallHalf[1] = num; sinkSmall(1); return; } } else if (num < largeHalf[1]) { if (lenSmall == lenLarge) { lenSmall++; smallHalf[lenSmall] = num; swimSmall(lenSmall); return; } else { lenLarge++; largeHalf[lenLarge] = num; swimLarge(lenLarge); return; } } else { if (lenSmall == lenLarge) { lenSmall++; smallHalf[lenSmall] = largeHalf[1]; swimSmall(lenSmall); largeHalf[1] = num; sinkLarge(1); return; } else { lenLarge++; largeHalf[lenLarge] = num; swimLarge(lenLarge); return; } } } public Double GetMedian() { // 奇数个数字 if (lenSmall > lenLarge) { return (double)smallHalf[1]; } return (smallHalf[1] + largeHalf[1]) / 2.0; } private void swimSmall(int k) { while (k > 1) { if (smallHalf[k] > smallHalf[k/2]) { swap(smallHalf, k, k/2); k /= 2; } else { break; } } } private void swimLarge(int k) { while (k > 1) { if (largeHalf[k] < largeHalf[k/2]) { swap(largeHalf, k, k/2); k /= 2; } else { break; } } } private void sinkSmall(int k) { while (2*k <= lenSmall) { int t = 2 * k; if (t+1 <= lenSmall && smallHalf[t] < smallHalf[t+1]) { t++; } if (smallHalf[k] >= smallHalf[t]) { break; } swap(smallHalf, k, t); k = t; } } private void sinkLarge(int k) { while (2*k <= lenLarge) { int t = 2 * k; if (t+1 <= lenLarge && largeHalf[t] > largeHalf[t+1]) { t++; } if (largeHalf[k] <= largeHalf[t]) { break; } swap(largeHalf, k, t); k = t; } } private void swap(int[] arr, int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } }