searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

最小的K个数-算法学习

2023-07-11 10:13:25
3
0

题目详情:
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
例如
输入:[4,5,1,6,2,7,3,8],4
返回值:[1,2,3,4]
说明:返回最小的4个数即可,返回[1,3,2,4]也可以


解题思路:

  1. 创建一个最大堆。
  2. 遍历整个数组,将数组中的元素依次插入最大堆中。
  3. 先将前k个元素先入队
  4. 在进行后面元素入队时,要先比较根节点值是否大于当前元素,如果根节点值>当前元素,就将根节点出队,当前元素入队
  5. 完成遍历后,堆中剩余的 k 个元素即为不去重的最小的 k 个数。

代码实现:
class MaxHeap {
    constructor() {
        this.heap = [];
    }

    getParentIndex(index) {
        return Math.floor((index - 1) / 2);
    }

    getLeftChildIndex(index) {
        return index * 2 + 1;
    }

    getRightChildIndex(index) {
        return index * 2 + 2;
    }

    swap(arr, i, j) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }

    shiftUp(index) {
        if (index === 0) {
            return;
        }
        const parentIndex = this.getParentIndex(index);
        if (this.heap[parentIndex] < this.heap[index]) {
            this.swap(this.heap, parentIndex, index);
            this.shiftUp(parentIndex);
        }
    }

    shiftDown(index) {
        const leftChildIndex = this.getLeftChildIndex(index);
        const rightChildIndex = this.getRightChildIndex(index);
        let maxIndex = index;
        if (
            leftChildIndex < this.heap.length &&
            this.heap[leftChildIndex] > this.heap[maxIndex]
        ) {
            maxIndex = leftChildIndex;
        }
        if (
            rightChildIndex < this.heap.length &&
            this.heap[rightChildIndex] > this.heap[maxIndex]
        ) {
            maxIndex = rightChildIndex;
        }
        if (maxIndex !== index) {
            this.swap(this.heap, maxIndex, index);
            this.shiftDown(maxIndex);
        }
    }

    insert(value) {
        this.heap.push(value);
        this.shiftUp(this.heap.length - 1);
    }

    pop() {
        if (this.heap.length === 0) {
            return -1;
        }
        if (this.heap.length === 1) {
            return this.heap.pop();
        }
        const top = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.shiftDown(0);
        return top;
    }

    peek() {
        if (this.heap.length === 0) {
            return -1;
        }
        return this.heap[0];
    }

    size() {
        return this.heap.length;
    }
}

function getLeastNumbers(numbers, k) {
    const n = numbers.length;
    if (k <= 0 || k > n) {
        return [];
    }
    const heap = new MaxHeap();
    for (let i = 0; i < n; i++) {
        if (i < k) {
            heap.insert(numbers[i]);
        } else if (numbers[i] < heap.heap[0]) {
            heap.pop();
            heap.insert(numbers[i]);
        }
    }
    const result = [];
    for (let i = 0; i < k; i++) {
        result.push(heap.pop());
    }

    return result;
}

// 测试示例
console.log(getLeastNumbers([4, 5, 1, 6, 2, 7, 3, 8], 4)); // 输出: [ 4, 3, 2, 1 ]

0条评论
作者已关闭评论
t****m
98文章数
1粉丝数
t****m
98 文章 | 1 粉丝
t****m
98文章数
1粉丝数
t****m
98 文章 | 1 粉丝
原创

最小的K个数-算法学习

2023-07-11 10:13:25
3
0

题目详情:
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
例如
输入:[4,5,1,6,2,7,3,8],4
返回值:[1,2,3,4]
说明:返回最小的4个数即可,返回[1,3,2,4]也可以


解题思路:

  1. 创建一个最大堆。
  2. 遍历整个数组,将数组中的元素依次插入最大堆中。
  3. 先将前k个元素先入队
  4. 在进行后面元素入队时,要先比较根节点值是否大于当前元素,如果根节点值>当前元素,就将根节点出队,当前元素入队
  5. 完成遍历后,堆中剩余的 k 个元素即为不去重的最小的 k 个数。

代码实现:
class MaxHeap {
    constructor() {
        this.heap = [];
    }

    getParentIndex(index) {
        return Math.floor((index - 1) / 2);
    }

    getLeftChildIndex(index) {
        return index * 2 + 1;
    }

    getRightChildIndex(index) {
        return index * 2 + 2;
    }

    swap(arr, i, j) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }

    shiftUp(index) {
        if (index === 0) {
            return;
        }
        const parentIndex = this.getParentIndex(index);
        if (this.heap[parentIndex] < this.heap[index]) {
            this.swap(this.heap, parentIndex, index);
            this.shiftUp(parentIndex);
        }
    }

    shiftDown(index) {
        const leftChildIndex = this.getLeftChildIndex(index);
        const rightChildIndex = this.getRightChildIndex(index);
        let maxIndex = index;
        if (
            leftChildIndex < this.heap.length &&
            this.heap[leftChildIndex] > this.heap[maxIndex]
        ) {
            maxIndex = leftChildIndex;
        }
        if (
            rightChildIndex < this.heap.length &&
            this.heap[rightChildIndex] > this.heap[maxIndex]
        ) {
            maxIndex = rightChildIndex;
        }
        if (maxIndex !== index) {
            this.swap(this.heap, maxIndex, index);
            this.shiftDown(maxIndex);
        }
    }

    insert(value) {
        this.heap.push(value);
        this.shiftUp(this.heap.length - 1);
    }

    pop() {
        if (this.heap.length === 0) {
            return -1;
        }
        if (this.heap.length === 1) {
            return this.heap.pop();
        }
        const top = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.shiftDown(0);
        return top;
    }

    peek() {
        if (this.heap.length === 0) {
            return -1;
        }
        return this.heap[0];
    }

    size() {
        return this.heap.length;
    }
}

function getLeastNumbers(numbers, k) {
    const n = numbers.length;
    if (k <= 0 || k > n) {
        return [];
    }
    const heap = new MaxHeap();
    for (let i = 0; i < n; i++) {
        if (i < k) {
            heap.insert(numbers[i]);
        } else if (numbers[i] < heap.heap[0]) {
            heap.pop();
            heap.insert(numbers[i]);
        }
    }
    const result = [];
    for (let i = 0; i < k; i++) {
        result.push(heap.pop());
    }

    return result;
}

// 测试示例
console.log(getLeastNumbers([4, 5, 1, 6, 2, 7, 3, 8], 4)); // 输出: [ 4, 3, 2, 1 ]

文章来自个人专栏
js
57 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0