zoukankan      html  css  js  c++  java
  • leetcode每日一题(2020-06-29):215. 数组中的第K个最大元素

    题目描述:
    在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

    今日学习:
    1.复习快速排序
    2.堆排序(大根堆、小根堆、建堆)
    3.复习冒泡排序
    题解:
    1.用sort()
    2.k次冒泡
    3.快速排序
    4.堆排序

    //1.取巧
    var findKthLargest = function(nums, k) {
        nums.sort((a, b) => b - a)
        return nums[k - 1]
    }; 
    //2.冒泡k次
    var findKthLargest = function(nums, k) {
        let count = k
        while(count != 0) {
            nums = bubble(nums)
            count--
        }
        return nums[nums.length - k]
    }
    var bubble = function(nums) {
        for(let i = 0; i < nums.length; i++) {
            if(nums[i] > nums[i + 1]) {
                [nums[i], nums[i + 1]] = [nums[i + 1], nums[i]]
            }
        }
        return nums
    }
    //3.快速排序
    const findKthLargest = (nums, k) => {
        const n = nums.length;
        const quick = (l, r) => {
            if (l > r) return;
            let random = Math.floor(Math.random() * (r - l + 1)) + l; // 随机选取一个index
            swap(nums, random, r); // 将它和位置r的元素交换,让 nums[r] 作为 pivot 元素
            //我们选定一个 pivot 元素,根据它进行 partition
            //partition 找出一个位置:它左边的元素都比pivot小,右边的元素都比pivot大
            //左边和右边的元素的是未排序的,但 pivotIndex 是确定下来的
            let pivotIndex = partition(nums, l, r);
            //我们希望这个 pivotIndex 正好是 n-k
            //如果 n - k 小于 pivotIndex,则在 pivotIndex 的左边继续找
            //如果 n - k 大于 pivotIndex,则在 pivotIndex 的右边继续找
            if (n - k < pivotIndex) { 
                quick(l, pivotIndex - 1);
            } else {
            quick(pivotIndex + 1, r);
            }
            //n - k == pivotIndex ,此时 nums 数组被 n-k 分成两部分
            //左边元素比 nums[n-k] 小,右边比 nums[n-k] 大,因此 nums[n-k] 就是第K大的元素
        };
        quick(0, n - 1); // 让n-k位置的左边都比 nums[n-k] 小,右边都比 nums[n-k] 大
        return nums[n - k]; 
    };
    function partition(nums, left, right) {
        let pivot = nums[right];             // 最右边的元素作为 pivot 元素
        let pivotIndex = left;               // pivotIndex 初始为 left
        for (let i = left; i < right; i++) { // 逐个考察元素,和 pivot 比较
            if (nums[i] < pivot) {             // 如果当前元素比 pivot 小
            swap(nums, i, pivotIndex);       // 将它交换到 pivotIndex 的位置
            pivotIndex++;                    
            }
        }                                    // 循环结束时,pivotIndex左边都是比pivot小的
        swap(nums, right, pivotIndex);       // pivotIndex和right交换,更新pivot元素
        return pivotIndex;                   // 返回 pivotIndex 下标
    }
    function swap(nums, p, q) {
        const temp = nums[p];
        nums[p] = nums[q];
        nums[q] = temp;
    }
    //4.堆排序
    let findKthLargest = function(nums, k) {
        // 从 nums 中取出前 k 个数,构建一个小顶堆
        let heap = [,], i = 0
        while(i < k) {
           heap.push(nums[i++]) 
        }
        buildHeap(heap, k)
        
        // 从 k 位开始遍历数组
        for(let i = k; i < nums.length; i++) {
            if(heap[1] < nums[i]) {
                // 替换并堆化
                heap[1] = nums[i]
                heapify(heap, k, 1)
            }
        }
        
        // 返回堆顶元素
        return heap[1]
    };
    // 原地建堆,从后往前,自上而下式建小顶堆
    let buildHeap = (arr, k) => {
        if(k === 1) return
        // 从最后一个非叶子节点开始,自上而下式堆化
        for(let i = Math.floor(k/2); i>=1 ; i--) {
            heapify(arr, k, i)
        }
    }
    // 堆化
    let heapify = (arr, k, i) => {
        // 自上而下式堆化
        while(true) {
            let minIndex = i
            if(2*i <= k && arr[2*i] < arr[i]) {
                minIndex = 2*i
            }
            if(2*i+1 <= k && arr[2*i+1] < arr[minIndex]) {
                minIndex = 2*i+1
            }
            if(minIndex !== i) {
                swap(arr, i, minIndex)
                i = minIndex
            } else {
                break
            }
        }
    }
    // 交换
    let swap = (arr, i , j) => {
        let temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
    }
    
  • 相关阅读:
    Struts2 语法--action
    react ref获取dom对象
    react 简单的用函数调出ui显示
    express.js graphql express-graphql
    Nestjs 增加全局前缀
    react使用BrowserRouter打包后,刷新页面出现404
    在node环境使用axios发送文件
    Nest js 使用axios模块
    Flutter For Web
    css实现开关效果
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13207830.html
Copyright © 2011-2022 走看看