题解
该题聚焦点为如何高效的对移动窗口内数据进行排序,当窗口已经有序的时候,向右移动一格,需要把新加入的数据替换掉该剔除的数据,此时就变成一个有序数组里有一个数是乱序的,此时只要将这一个乱序数进行插入排序即可。总的时间复杂度为 n*O(n)
代码
var medianSlidingWindow = function(nums, k) {// 记录结果let ret = []// 窗口数组let arr = nums.slice(0, k)// 首次进行快排quickSort(arr)// 放入第一个中位数ret.push(calcMid(arr))// 遍历原数组for (let i = 1; i <= nums.length - k; i++) {binarySearchSort(arr, nums[i-1], nums[i-1+k])ret.push(calcMid(arr))}return ret};function calcMid(arr) {let sum = arr.length - 1if (sum % 2 === 0) {return arr[sum/2]} else {let mid = Math.floor(sum/2)return (arr[mid] + arr[mid + 1]) / 2}}function quickSort(arr) {arr.sort((a, b) => a - b)}function binarySearchSort(arr, remove, add) {// 使用 add 替换 remove 并返回 remove 所在位置let index = binarySearchReplace(arr, remove, add)// 重新排序,从 index 位置进行一次插入排序insertSortFromIndex(arr, index)}function insertSortFromIndex(arr, index) {let flag = falsewhile (index >= 1 && arr[index - 1] > arr[index]) {[arr[index - 1], arr[index]] = [arr[index], arr[index - 1]]index--flag = true}if (flag) returnwhile (index < arr.length - 1 && arr[index + 1] < arr[index]) {[arr[index + 1], arr[index]] = [arr[index], arr[index + 1]]index++}}function binarySearchReplace(arr, remove, add) {let index = binarySearch(arr, remove, 0, arr.length - 1)arr[index] = addreturn index}function binarySearch(arr, target, start, end) {if (start <= end) {let mid = Math.floor((start + end) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {start = mid + 1return binarySearch(arr, target, start, end)} else {end = mid - 1return binarySearch(arr, target, start, end)}} else {return -1}}
