算法打卡第十七天

92 阅读1分钟
  1. 剑指 Offer 40. 最小的k个数
  2. 剑指 Offer 41. 数据流中的中位数

剑指 Offer 40. 最小的k个数

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

题意理解: 找出数组最小的k个数,可以不在乎顺序 参考讲解快速排序

  1. 边界判断,根据限制可得,当arr.length === k,是直接返回arr,不考虑arr.length < k的情况
  2. 快排函数 终止条件k===基准
  3. k<基准数,在只排右边即可
  4. k>基准数,在只排左边即可

限制: 0 <= k <= arr.length <= 10000 0 <= arr[i] <= 10000

示例 1: 输入:arr = [3, 2, 1], k = 2 输出:[1, 2] 或者 [2, 1]

示例 2: 输入:arr = [0, 1, 2, 1], k = 1 输出:[0]

var getLeastNumbers = function(arr, k) {
    if (arr.length === k) {
        return arr;
    }

    function quickSort(arr, left, right) {
        if (left < right) {
            const partitionIndex = partition(arr, left, right);
            if (partitionIndex === k) {
                return
            } else if (partitionIndex < k) {
                quickSort(arr, partitionIndex + 1, right);
            } else {
                quickSort(arr, left, partitionIndex - 1);
            }
        }
    }

    // 找基准
    function partition(arr, left, right) {
        let pivot = left,
            index = pivot + 1;
        for (let i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap(arr, i, index);
                index++;
            }
        }
        swap(arr, pivot, index - 1);
        return index - 1;
    }

    function swap(arr, i, j) {
        let temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    quickSort(arr, 0, arr.length - 1)
    const res = [];
    for (let i = 0; i < k; i++) {
        res[i] = arr[i]
    }
    return res;
}

剑指 Offer 41. 数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

题意理解: 实现两个方法,一个用来添加数据,一个用来返回数据中的中位数

  1. 在每次进行插入数据时,就对数据进行排序存储,并把中位数计算出来,保存到变量中
  2. 找到要插入数据的位置,及比前一个数大,比后一个数小
  3. 利用数据自带方法进行插入

次解法不是最优解,最优解正在学习中,目前有点难搞懂

var MedianFinder = function () {
    this.median = null;
    this.arr = [];
};

MedianFinder.prototype.addNum = function (num) {
    let arr = this.arr;
    let index = -1;
    for (let i = 0; i < arr.length; i++) {
        if (num > arr[i]) {
            index = i;
        }
    }
    if (index===-1) {
        this.arr = [num, ...arr.slice(index + 1)];
    } else {
        this.arr = [...arr.slice(0, index+1), num, ...arr.slice(index + 1)];
    }
    const length = this.arr.length;
    if (length % 2 === 1) {
        this.median = this.arr[Math.floor(length / 2)]
    } else {
        this.median = (this.arr[length / 2 - 1] + this.arr[length / 2]) / 2
    }
};

MedianFinder.prototype.findMedian = function () {
    return this.median
};