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
    }
    
  • 相关阅读:
    Java Output流写入包装问题
    SpringBoot项目单元测试不经过过滤器问题
    SpringSecurity集成启动报 In the composition of all global method configuration, no annotation support was actually activated 异常
    JWT jti和kid属性的说明
    Maven 排除依赖
    第五章 基因概念的发现
    第三章 孟德尔遗传的拓展
    第二章 孟德尔遗传
    第一章 引言
    GWAS全基因组关联分析
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13207830.html
Copyright © 2011-2022 走看看