数组中的第K个最大元素Scala实现

 

 

 


前言

运用Scala的语法实现数组中的第K个最大元素


 

一、数组中的第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

二、实现步骤

代码如下(示例):

利用 partition分区函数,初始将最后一个元素arr[len-1]作为 pivot(分区点),
将数组中小于 pivot 的点都放置到其左边,将大于pivot的点都放置在其右边,最终 partition 函数返回 pivot 的下标 i
1当 partition 函数返回的下标 i=len-k,则 arr[i] 就是我们要求的第K大元素
2、当 partition 函数返回的下标 i<len-k,那么说明第K大元素在下标 i 的右边,我们继续分区在 arr[i+1, len-1] 区间内查找:partition(arr, i+1, len-1)
3、当 partition 函数返回的下标 i>len-k,那么说明第K大元素在下标 i 的左边,我们继续分区在 arr[0, i-1] 区间内查找:partition(arr, 0, i-1)
def findKthLargest(nums: Array[Int], k: Int): Int = {
  val len=nums.length
  val resIndex=len-k//结果元素的索引
  //pivot点刚好是第K大元素,那么它的左边一定有 K-1 个不小于它的元素,它的下标应该是 len-k
  var left=0
  var right=len-1
  while(true){
    val ind=partition(nums,left,right)
    if (ind==resIndex)
      return nums(ind)
    else if(ind>resIndex)//说明第K大元素在下标 i 的左边,我们继续分区在 arr[0, i-1] 区间内查找
      right=ind-1
    else //说明第K大元素在下标 i 的右边,我们继续分区在 arr[i+1, len-1] 区间内查找
      left=ind+1
  }
  Int.MinValue
}
分区函数,将 arr[high] 作为 pivot 分区点
i、j 两个指针,i 作为标记“已处理区间”和“未处理区间”的分界点,也即 i 左边的(low~i-1)都是“已处理区”。
j 指针遍历数组,当 arr[j] 小于 pivot 时,就把 arr[j] 放到“已处理区间”的尾部,也即是 arr[i] 所在位置
因此 swap(arr, i, j) 然后 i 指针后移,i++
直到 j 遍历到数组末尾 arr[high],将 arr[i] 和 arr[high](pivot点) 进行交换,返回下标 i,就是分区点的下标。
def partition(arr:Array[Int],left:Int,right:Int): Int ={
  if (right > left) {//当数组近乎有序时
    //在下标 low 和 high 之间随机选择,然后和下标 high 元素进行交换
   val random = left +Random.nextInt(right-left);
    swap(arr, right, random);
  }
  var i=left
  val pivot=arr(right)
  for(j <- left until right if arr(j)<pivot) {
    swap(arr,i,j)
    i+=1
  }
  swap(arr,i,right)
  i
}

def swap(arr:Array[Int],i:Int,j:Int): Unit ={
  val tmp=arr(i)
  arr(i)=arr(j)
  arr(j)=tmp
}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值