剑指Offer专项突破版(76)—— 数组中的第 k 大的数字
创始人
2024-03-02 11:41:29

题目

剑指 Offer II 076. 数组中的第 k 大的数字
在这里插入图片描述

思路

假设有个划分函数divide:

  • divide:将num在[l,r]范围内,按照nums[l]进行划分,返回一个数组range,划分为:

    • 所有小于nums[l]的数:移动到nums[l,range[0]-1]
    • 所有等于nums[l]的数:移动到nums[range[0],range[1]]
    • 所有大于nums[l]的数:移动到nums[range[1+1],r]

我们要找第k大的数,可以转化为求第nums.length - k + 1小的数

对nums在[0,nums.length-1]范围内做划分,结果为range:

  • 如果k就在range的范围内,即 k >= range[0] && k <= range[1],说明第k小的数就是nums[range[0]]
  • 如果k < range[0],说明第k小的数在前半段,即nums[0,range[0]-1]中,那就在这个范围内去递归处理
  • 如果k > range[0],说明第k小的数在后半段,即nums[range[1]+1,]中,那就在这个范围内去递归处理

最后看看divide怎么实现:

由于最终需要将数组nums在[l,r]范围内划分为4个区域,因此需要定义这3个区域的边界:

  • 小于nums[l]的区域[l+1,less]

    • 一开始所有区域的范围都是0,因此less初始化为l
  • 等于nums[l]的区域[less+1,i-1]

    • 等于区域一定紧跟着小于区域,因此左边界为less+1
    • 其右端点为当前遍历的位置的前一个位置,也就是i-1
    • i会初始化为l+1,因此等于区域的初始范围也是0个元素
  • 大于nums[l]的区域[more,r]

    • 因为需要初始化为0个元素,因此more初始化为r+1
  • 最后还剩下一个未定区域:[i,more-1]

接着从l+1开始遍历每个元素i,如果

  • nums[ i ]等于nums[l] :什么都不用处理,i++
  • nums[ i ]小于nums[l] :将nums[i]和等于区域的第一个数交换,将小于区域的右边界less++

    • 实质是扩充小于区域
    • 交换过来的数等于nums[l],因此i++,继续后面的循环
    • 这样操作后,整个数组依旧维持4个区域的定义
  • nums[ i ]大于于nums[l] :将nums[i]和大于区域的前一个数交换,将大于区域的左边界–

    • 实质是扩充大于区域
    • 此时由于不清楚交换过来的数和nums[l]的关系,因此需要重新进入循环
    • 这样操作后,整个数组依旧维持4个区域的定义

在这里插入图片描述

什么时候结束循环呢?

当i和more相撞的时候,表示数组中所有的数都遍历过了,且都在正确的位置上

代码

class Solution {public int findKthLargest(int[] nums, int k) {k = nums.length - k + 1 -1 ;int l = 0;int r = nums.length-1;while(true) {int[] range = divide(nums,l,r);if(k >= range[0] && k <= range[1]) {return nums[k];}if(k < range[0]) {r = range[0]-1;} else {l = range[1] + 1;}}}private int[] divide(int[] nums,int l,int r) {if(l == r) {return new int[]{l,l};}int p = nums[l];// 大于[more,r]int more = r + 1;// 小于[l+1,less]// 等于[less+1,i-1]int less = l;int i = l + 1;for(;iif(nums[i] < p){swap(nums,i,less+1);i++;less++;} else if(nums[i] > p) {swap(nums,i,more-1);more--;} else {i++;}}// 等于区域 [less+1,i-1]swap(nums,l,less);return new int[]{less,i-1};}private void swap(int[] nums,int a,int b) {int temp = nums[a];nums[a] = nums[b];nums[b] = temp;}
}

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...