当前位置: 首页 > news >正文

快速排序题目SelectK问题

力扣75.颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

 

class Solution { //时间复杂度为O(n)//其实,变量 zero 相当于我们在三路快速排序算法中的 lt;//变量 two 相当于我们在三路快速排序算法中的 gt。public void sortColors(int[] nums) {// nums[0...zero] == 0, nums[zero + 1, i] == 1, nums[two, n - 1] == 2// 定义三个指针:zero、i、two,分别表示0的最右边界、当前处理的元素、2的最左边界int zero = -1, i = 0, two = nums.length;while(i < two){// 当前处理元素的指针小于2的最左边界时,继续循环// 如果当前元素为0,将其与zero右边的元素交换,并将zero和i都向右移动一位if(nums[i] == 0){zero++;swap(nums,zero,i);i++;}// 如果当前元素为2,将其与two左边的元素交换,并将two向左移动一位else if (nums[i] == 2){ // 注意此时不需要i右移,因为交换后的元素还需要继续判断two --;swap(nums, i, two);}else{ //如果当前元素是1,不需要操作,直接继续向右遍历i ++;}}}// 交换数组中指定位置的两个元素private void swap(int[] nums, int i, int j){int t = nums[i];nums[i]= nums[j];nums[j] = t;}
}


我们首先来封装一个 selectK 的方法。封装好了这个方法以后,这三个问题都可
以快速求解。
我们的 selectK 的接口是这样的:
// 在 arr[l...r] 的范围里求解整个数组的第 k 小元素并返回
// k 是索引,即从 0 开始计算
int selectK(int[] arr, int l, int r, int k, Random rnd)
因为我们的 partition 过程需要随机选取标定点,所以我们还需要传一个 Random(快排的优化)
类的对象 rnd。
定义好函数签名以后,下面我们来书写相应的逻辑。
首先,selectK 的过程,我们就是要执行一遍 partition。在这里,我使用双路快速
排序的 partition。
注意,因为在这个问题中,我们肯定我们处理的数据类型是 int,所以,在代码
中,我不再使用泛型:

private int partition(int[] arr, int l, int r, Random rnd){// 生成 [l, r] 之间的随机索引int p = l + rnd.nextInt(r - l + 1);swap(arr, l, p);// arr[l+1...i-1] <= v; arr[j+1...r] >= vint i = l + 1, j = r;while(true){while(i <= j && arr[i] < arr[l])i ++;while(j >= i && arr[j] > arr[l])j --;if(i >= j) break;swap(arr, i, j);i ++;j --;
}swap(arr, l, j);return j;
}
private void swap(int[] arr, int i, int j){int t = arr[i];arr[i] = arr[j];arr[j] = t;
}

有了 partition,我们的 selectK 的主题逻辑非常简单。

首先,进行 partition,假设结果是 p。我们只需要将 k 和 p 做比较。

  • 如果 k == p,直接返回 arr[p] 即可;
  • 如果 k < p,在 arr[l, p - 1] 的范围继续找,即调用 selectK(arr, l, p - 1, k, rnd);
  • 如果 k > p,在 arr[p + 1, r] 的范围继续找,即调用 selectK(arr, p + 1, r, k, rnd);

就有了下面的代码:

private int selectK(int[] arr, int l, int r, int k, Random rnd){
int p = partition(arr, l, r, rnd);
if(k == p) return arr[p];
if(k < p) return selectK(arr, l, p - 1, k, rnd);return selectK(arr, p + 1, r, k, rnd);
}

这样,我们就完成了 select K 的过程。是不是非常简单!

下面,我们用我们写的 select K,先来解决 Leetcode 上第 215 号问题:

这个问题是求第 k 大元素,但是我们的 selectK 求得是第 k 小元素。怎么办?
非常简单,我们只需要在调用 select K 之前,将求第 k 大元素的这个 k,转换成
对应求的是第几小元素对应的索引就好了。
按照题目描述,如果 k 是 1,对应就是要找最大元素,那么相应的我们的
select K 的索引,就是 nums.length - 1。(如果10个数,K=1,第一个最大的数,就是SelectK索引为9的那个的元素)
如果 k 是 nums.length,其实就是求最小元素,那么相应的我们的 selectK 的
索引,就是 0。  (如果10个数,第10个最大的数,就是SelectK索引为0的那个的元素,最小值)
他们之间的转换关系是 nums.length - k。

力扣215.数组中的第K个最大元素 

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

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

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

import java.util.Random; //导入Random包
class Solution {public int findKthLargest(int[] nums, int k) {//只有两行,其他的内容全部复用我们上面实现的 selectK,是不是很酷?//我们的SelectK是第K最小元素,所以这里findKthLargest传入下标要处理一下//转换关系是 nums.length - kRandom rnd = new Random();return selectK(nums, 0, nums.length - 1, nums.length - k, rnd);}//有了 partition,我们的 selectK 的主题逻辑非常简单。private int selectK(int[] arr, int l, int r, int k, Random rnd){//首先,进行 partition,假设返回值结果是 p。我们只需要将 k 和 p 做比较。int p = partition(arr, l, r, rnd); //如果 k == p,直接返回 arr[p] 即可;if(k == p) return arr[p]; //如果 k < p,在 arr[l, p - 1] 的范围继续找,即调用 selectK(arr, l, p - 1, k, rnd);if(k < p) return selectK(arr, l, p - 1, k, rnd); //如果 k > p,在 arr[p + 1, r] 的范围继续找,即调用 selectK(arr, p + 1, r, k, rnd);return selectK(arr, p + 1, r, k, rnd);
}private int partition(int[] arr, int l, int r, Random rnd){// 生成 [l, r] 之间的随机索引int p = l + rnd.nextInt(r - l + 1);swap(arr, l, p);// arr[l+1...i-1] <= v; arr[j+1...r] >= vint i = l + 1, j = r;while(true){while(i <= j && arr[i] < arr[l])i ++;while(j >= i && arr[j] > arr[l])j --;if(i >= j) break;swap(arr, i, j);i ++;j --;}swap(arr, l, j);return j;}//数组指定索引,两数交换private void swap(int[] arr, int i, int j){int t = arr[i];arr[i] = arr[j];arr[j] = t;}
}

相关文章:

快速排序题目SelectK问题

力扣75.颜色分类 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sor…...

es6解构赋值

ES6解构赋值是一种简洁的为变量赋值的方式&#xff0c;它允许我们从数组或对象中提取值并赋给对应的变量。 解构赋值在ES6中被引入&#xff0c;主要目的是为了简化代码&#xff0c;提高代码的可读性。以下是解构赋值的基本用法&#xff1a; 数组解构&#xff1a;当我们需要从数…...

Jenkins上面使用pnpm打包

问题 前端也想用Jenkins的CI/CD工作流。 步骤 Jenkins安装NodeJS插件 安装完成&#xff0c;记得重启Jenkins。 全局配置nodejs Jenksinfile pipeline {agent anytools {nodejs "18.15.0"}stages {stage(Check tool version) {steps {sh node -vnpm -vnpm config…...

设计编程网站集:动物,昆虫,蚂蚁养殖笔记

入门指南 区分白蚁与蚂蚁 日常生活中&#xff0c;人们常常会把白蚁与蚂蚁搞混淆&#xff0c;其实这两者是有很大区别的&#xff0c;养殖方式差别也很大。白蚁主要食用木质纤维&#xff0c;会给家庭房屋带来较大危害&#xff0c;而蚂蚁主要采食甜食和蛋白质类食物&#xff0c;不…...

面经学习(众智宏图实习)

个人评价 难度还是有的&#xff0c;中等难度吧&#xff0c;可能是因为项目使用的是物流项目&#xff0c;该项目本来就比较庞大难度比较高&#xff0c;流的八股文我真的是一点不会&#xff0c;还需要加强&#xff0c;reidis的多路io复用模型没有深问&#xff0c;要是问了就寄了&…...

DataGrip2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 DataGrip是由JetBrains公司开发的一款强大的关系数据库集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为数据库开发人员和数据库管理员设计。它提供了一个统一的界面&#xff0c;用于管理和开发各种关系型数据库&#x…...

【InternLM 实战营第二期-笔记4】XTuner 微调个人小助手认知

书生浦语是上海人工智能实验室和商汤科技联合研发的一款大模型,很高兴能参与本次第二期训练营&#xff0c;我也将会通过笔记博客的方式记录学习的过程与遇到的问题&#xff0c;并为代码添加注释&#xff0c;希望可以帮助到你们。 记得点赞哟(๑ゝω╹๑) XTuner 微调个人小助手…...

<计算机网络自顶向下> CDN

视频服务挑战 规模性异构性&#xff1a;不同用户有不同的能力&#xff08;比如有线接入和移动用户&#xff1b;贷款丰富和受限用户&#xff09;解决方法是&#xff1a;分布式的应用层面的基础设施CDN 多媒体&#xff1a;视频 视频是固定速度显示的一系列图像的序列&#xff…...

【Git教程】(十二)工作流之项目设置 — 何时使用工作流,工作流的结构,项目设置概述、执行过程及其实现 ~

Git教程 工作流之项目设置 1️⃣ 何时使用工作流2️⃣ 工作流的结构3️⃣ 概述4️⃣ 使用要求5️⃣ 执行过程及其实现5.1 基于项目目录创建一个新的版本库5.2 以文件访问的方式共享版本库5.3 用 Git daemon 来共享版本库5.4 用 HTTP 协议来共享版本库5.5 用 SSH 协议来共享版…...

Java 排序算法

冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复地遍历要排序的数列&#xff0c;比较相邻元素的大小并交换位置&#xff0c;使得较大的元素逐渐向数列的末尾移动。 以下是Java实现的冒泡排序代码&#xff1a; public stat…...

【重磅更新】开源表单系统填鸭表单v5版发布!

亲爱的TDucker&#xff0c;你们好。 真诚感谢您对填鸭表单的关注与支持。今天我们将为您带来新版本的更新说明&#xff0c;以便您更好的使用我们的产品。 社区版版V5更新概览&#xff1a; ✅ 增加WebHook数据推送功能&#xff0c;集成TReport实现数据大屏展示。 ✅ 增加主题…...

保姆级教程 | Adobe Illustrator 中插入数学符号

背景 鉴于Adobe Illustrator作为比较专业的绘图/组图软件&#xff0c;我的论文数据作图都会选择先在origin中把原始数据绘制好&#xff0c;后都放入AI中细修。由于在作图过程中需要插入数学符号&#xff0c;但仿佛没有PowerPoint用起来那么熟悉&#xff0c;遂记录下。 步骤 …...

数据结构——双向循环链表

目录 前言 一、链表的分类 二、双向循环链表 2.1 开辟新的节点 2.2 链表初始化 2.3 打印链表 2.4 链表的尾插 2.5 链表的头插 2.6 链表的尾删 2.7 链表的头删 2.8 查找链表 2.9 在pos位置之后插入数据 2.10 删除pos位置的数据 三、完整代码实现 四、顺序表和双向…...

使用ZLMediaKit搭建服务器实现推流拉流

源码&#xff1a;https://gitee.com/xia-chu/ZLMediaKit?utm_sourcealading&utm_campaignrepo 文档&#xff1a;https://docs.zlmediakit.com/zh/tutorial/ 检查gcc版本gcc -v检查cmake是否安装cmake --version安装gitsudo apt-get install git按照文档进行克隆 # 国内用…...

【拦截器Interceptor】springboot拦截器的使用和原理

【拦截器Interceptor】springboot拦截器的使用和原理 【一】拦截器简介&#xff08;1&#xff09;简介【2】作用 【二】实现步骤【1】自定义拦截器&#xff0c;实现拦截器接口HandlerInterceptor【2】将拦截器添加到容器当中【3】配置拦截器的拦截规则【4】拦截器的执行顺序 【…...

Android12 user版本无法进入recovery问题

1.前言 之前Android9的时候公司自己写了一个简单的OTA在线升级&#xff0c;调用Recovery升级系统。后来Android12的时候想使用AB升级&#xff0c;发现我这套代码AB升级完成了之后&#xff0c;重启却无法切到B&#xff0c;所以造成升级一直是失败的。后来想着要不还是把AB关掉直…...

Android沙盒机制

Android沙盒机制 Android Q文件存储机制修改成了沙盒模式&#xff0c;应用只能访问自己沙盒下的文件和公共媒体文件 存储&#xff08;也就是write&#xff09;私有目录和公共媒体文件都不需要WRITE_EXTERNAL_STORAGE权限读取&#xff08;也就是read&#xff09;私有目录不需要…...

【C++】每日一题 290 单词规律

给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 这里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 #include <string> #include <unordered_ma…...

CSS3 animation-direction 属性

CSS3 animation-direction 属性 定义和用法 animation-direction 属性定义是否循环交替反向播放动画。 **注意&#xff1a;**如果动画被设置为只播放一次&#xff0c;该属性将不起作用。 默认值&#xff1a;normal继承&#xff1a;否可动画化&#xff1a;否。请参阅 可动画…...

【mysql 5.7 没有ini 文件,手动添加配置文件】

在安装目录的根目录添加my.ini配置文件&#xff1a; 注意注释的内容&#xff0c; 其中server-id 在开启日志归档的时候&#xff0c;一定要配置&#xff0c; [mysql] # 设置mysql客户端默认字符集 default-character-setutf8[mysqld] #server id 一定要设置&#xff0c;否则无法…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

【系统架构设计师-2025上半年真题】综合知识-参考答案及部分详解(回忆版)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20~21题】【第…...