首页 > 其他分享 >每日一题 --- 数组中的第 K 个最大元素[力扣][Go]

每日一题 --- 数组中的第 K 个最大元素[力扣][Go]

时间:2024-03-27 14:05:00浏览次数:31  
标签:--- return nums int pos len 力扣 func Go

数组中的第 K 个最大元素

题目:数组中的第 K 个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

提示:

  • 1 <= k <= nums.length <= 104
  • -104 <= nums[i] <= 104

方法一:

使用快速排序,排好序后找到第K大的元素。

func findKthLargest(nums []int, k int) int {
   if len(nums) < k {
      return -1
   }
   qSort(nums)
   return nums[len(nums)-k]
}

func qSort(nums []int) {
   quickSort(nums, 0, len(nums)-1)
}

// 快速排序算法
func quickSort(nums []int, min, max int) {
   if min < max {
      pos := partition(nums, min, max)
      quickSort(nums, min, pos-1)
      quickSort(nums, pos+1, max)
   }
}

func partition(nums []int, l, r int) int {
   base := nums[l]
   for l < r {
      for l < r && nums[r] >= base {
         r--
      }
      nums[l] = nums[r]
      for l < r && nums[l] <= base {
         l++
      }
      nums[r] = nums[l]
   }
   nums[l] = base
   return l
}

方法二:

使用堆排序,排好序后,调整K次大根堆,然后取出元素值

func findKthLargest(nums []int, k int) int {
   // 实现卫兵
   nums = append([]int{0}, nums...)
   Len := len(nums)
   buildMaxHeap(nums, Len-1)
   for i := Len - 1; i >= Len-k; i-- {
      nums[1], nums[i] = nums[i], nums[1]
      maxHeapAdjust(nums, 1, i-1)
   }
   return nums[Len-k]
}

// 建堆
func buildMaxHeap(nums []int, len int) {
   for i := len / 2; i > 0; i-- {
      maxHeapAdjust(nums, i, len)
   }
}

// 调整堆, k为根元素,从k开始往下调整
func maxHeapAdjust(nums []int, k, len int) {
   nums[0] = nums[k]
   for i := 2 * k; i <= len; i *= 2 {
      if i < len && nums[i] < nums[i+1] {
         i++
      }
      if nums[i] <= nums[0] {
         break
      } else {
         nums[k] = nums[i]
         k = i
      }
   }
   nums[k] = nums[0]
}

方法一和方法二都是采取,先排序再取值的办法。时间复杂度为O(n*log n)。

其实我们可以改进下方法一:利用分治思想将时间复杂度期望降至O(1)。

具体思想讲解:4.3分治寻找第k小元素_哔哩哔哩_bilibili

在这里插入图片描述

方法三:

分治法,与上面思想不同的是,我们不执着于找中位数,而是采用随机分治,当随机到的基数正好为第K大时,直接返回。详细讲解参考力扣题解部分。

func findKthLargest(nums []int, k int) int {
   if len(nums) < k {
      return -1
   }
   return qSort(nums, len(nums)-k)
}

func qSort(nums []int, index int) int {
   rand.Seed(time.Now().UnixNano())
   return quickSort(nums, 0, len(nums)-1, index)
}

// 快速排序算法
func quickSort(nums []int, min, max, index int) int {
   randN := rand.Int()%(max-min+1) + min
   pos := partition(nums, min, max, randN)
   if pos == index {
      return nums[pos]
   } else if pos < index {
      return quickSort(nums, pos+1, max, index)
   } else {
      return quickSort(nums, min, pos-1, index)
   }

}

func partition(nums []int, l, r, random int) int {
   nums[random], nums[l] = nums[l], nums[random]
   base := nums[l]
   for l < r {
      for l < r && nums[r] >= base {
         r--
      }
      nums[l] = nums[r]
      for l < r && nums[l] <= base {
         l++
      }
      nums[r] = nums[l]
   }
   nums[l] = base
   return l
}

理论上期望时间复杂度为O(n),求证:算法导论中文版.pdf · FaithLight/books - Gitee.com,定位:《算法导论》9.2

标签:---,return,nums,int,pos,len,力扣,func,Go
From: https://blog.csdn.net/weixin_52025712/article/details/137042879

相关文章

  • d3d12龙书阅读----绘制几何体(上)
    d3d12龙书阅读----绘制几何体(上)本节主要介绍了构建一个简单的彩色立方体所需流程与重要的api下面主要结合立方体代码分析本节相关知识顶点输入装配器阶段的输入首先,我们需要定义立方体的八个顶点顶点结构体:structVertex{XMFLOAT3Pos;XMFLOAT4Color;};当然......
  • [转帖]SPECjbb MultiJVM - Java Performance
     MovingonfromSPECCPU,weshiftovertoSPECjbb2015.SPECjbbisafromground-updevelopedbenchmarkthataimstocoverbothJavaperformanceandserver-likeworkloads,fromtheSPECwebsite:“TheSPECjbb2015benchmarkisbasedontheusagemodelofa......
  • 求助,路过的大佬帮忙看一下!!!!elment中input组件使用prefix-icon="el-icon-search"不加载
    背景:创建了一个简单的vue工程想用测试一下el-input组件的功能,没有显示图标。代码如下所示<template><el-inputv-model="value"placeholder="请输入内容":disabled="false":show-password="true":clearable="true"prefix......
  • Wireshark使用实训---分析IP包
    1.Wireshark简介和作用Wireshark是一个开源的网络分析工具,用于捕捉和分析网络数据包。它可以帮助网络管理员和安全专家监控和解决网络问题,同时也可以用于学习和教学网络通信原理。Wireshark可以在网络中捕获和分析传输的数据包,包括协议头部信息和数据负载。它支持多种网络协......
  • pretty-printers:更优雅的看GDB堆栈信息
    在GDB中,你可以使用print命令(p)打印一个各种对象的内容。但是GDB默认的打印格式可能不是很易读,特别是对于复杂的数据结构。为了得到更易于阅读的输出,你可以使用prettyprinters。prettyprinters是一些特殊的脚本,它们可以改变GDB打印对象的方式。gitclonehttps://gcc.gnu.org/gi......
  • 极高创新性!基于斑马算法优化并行卷积神经网络注意力机制结合支持向量机ZOA-PCNN-AT-SV
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。......
  • C语言-实现文件操作
    0.前言:    我们知道下载东西,电脑上就会有各种的文件夹及文件里面的内容,那么文件里面的数据怎么通过编写程序来帮我们获取呢,这些文件又是怎么创建的呢?C语言给我们提供了一些可以操作文件的函数。这里我只列举了一部分操作文件的函数,使用这些函数需要引入头文件<stdlib.......
  • SpringBootWeb最新相关技术(上接maven):IDEA2023-Spring环境,http协议复习概览,web服务器To
    Spring官网HTTPs://spring.iospring生态(全家桶)基于SpringFramework基础框架。但如果我们基于该基础框架开发,会面临配置繁琐,入门难度大的问题,SpringBoot则可以快速开发(简化配置,快速开发)。1.SpringBootWeb入门使用SpringBoot开发一个Web应用,浏览器发起请求/hello之后,给浏......
  • 用 AI 给人生开挂的正确方式 - 在 AI 迅速进化的时代,我们应该如何不落伍
    作者:明明如月学长,CSDN博客专家,大厂高级Java工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。热门文章推荐:(1)《为什么很多人工作3年却只有1年经验?》(2)《一文掌握大模型提示词技巧:......
  • L2-028 秀恩爱分得快
    可恶的模拟,借鉴了别人的思路,这样写很清晰#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e5+10;constintinf=0x3f3f3f3f;constintmod=1e9+7;intn,q,m;vector<int>a,b;doubleg[1010][1010];doublemaxn[1010];set<......