每日一题- day 3

130 阅读1分钟

1. 今日语录

数据结构的掌握是算法学习的基础。

2. 题目

题如其名

3. 思路

const arr = [3, 2, 3, 1, 2, 4, 5, 5, 6]
const k = 4
/**
 * 解法1 数组暴力排序
 */
const sort_0 = (arr, k) => {
    return arr.sort((a, b) => b - a)[k - 1]
}
/**
 * 解法2 快速排序训练一波
 */
const sort_1 = (arr, k) => {
    const Partition = (nums, l, r) => {
        let pivot = nums[l];
        while (l < r) {
            //从右往左,找到第一个比pivot小的
            while (l < r && nums[r] >= pivot) {
                r--;
            }
            // 右边位置空出来了
            nums[l] = nums[r]
            // 从左往右,找到第一个比pivot大的
            while (l < r && nums[l] <= pivot) {
                l++;
            }
            // 左边位置空出来了
            nums[r] = nums[l]
        }
        nums[l] = pivot;
        return l;
    }
    const quickSort = (arr, l, r) => {
        if (l < r) {
            let pivot = Partition(arr, l, r);
            quickSort(arr, l, pivot - 1)
            quickSort(arr, pivot + 1, r)
        }
    }
    quickSort(arr, 0, arr.length - 1)
    return arr[arr.length - k]
}
/**
 * 解法3
 * 使用堆排序来解决这个问题——建立一个大根堆,做 k−1 次交换后,堆顶元素
 * 就是我们要找的答案。
 */
const sort_2 = (nums, k) => {
    let len = nums.length;
    const swap = (i, j) => {
        let temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    // 核心功能,左右比较大小,大的结点向上挪动(交换)
    const maxHeapify = (i, size) => {
        let l = 2 * i + 1;
        let r = 2 * i + 2;
        let max = i;
        if (l < size && nums[l] > nums[max]) {
            max = l;
        }
        if (r < size && nums[r] > nums[max]) {
            max = r;
        }
        if (max !== i) {
            // 左右节点值较大的 与 i 交换
            swap(max, i);
            // max进行递归
            maxHeapify(max, size);
        }
    }
    const buildMaxHeap = () => {
        // i 取 一半 ,对应从尾部几个节点开始交换,建立大根堆
        for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {
            maxHeapify(i, len)
        }
    }
    //建立好大根堆
    buildMaxHeap()
    // 交换 k -1 次 堆根节点与尾部节点
    for (let i = nums.length - 1; i >= nums.length - (k - 1); i--) {
        swap(i, 0)
        len--;
        maxHeapify(0, len);
    }
    return nums[0]
}
const fn = () => {
    console.log(`[${arr}] 第 ${k} 个最大元素 = `, sort_0(arr, k));
    console.log(`[${arr}] 第 ${k} 个最大元素 = `, sort_1(arr, k));
    console.log(`[${arr}] 第 ${k} 个最大元素 = `, sort_2(arr, k));
}
fn()

4. 关键字

堆排序、快速排序