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

【算法专场】分治(上)

目录

前言

什么是分治?

75. 颜色分类

算法分析

算法步骤

算法代码

912. 排序数组 - 力扣(LeetCode)

算法分析

算法步骤

算法代码

215. 数组中的第K个最大元素 - 力扣(LeetCode)

算法分析

算法步骤

​编辑 

算法代码

LCR 159. 库存管理 III - 力扣(LeetCode) 

算法分析

算法步骤

算法代码


前言

在前面,我们学习了八大排序,那么其中的快速排序和归并排序都用到了分治的思想。在算法中,有时候我们也需要利用分治的思想来解决一些算法问题。本篇我们主要讲解快速排序。

什么是分治?

分治算法是一种算法设计策略,将大问题转化为小问题,再将小问题转化为更小的问题,通过解决子问题来大问题。也就是说,把问题分解成若干个规模较小的问题,然后通过递归的方法来解决这些子问题,最后将子问题合并起来得到想要的结果。

步骤:

  1. 分解:将问题分解成若干个较小且独立的子问题,一般是通过递归实现;
  2. 解决:分解成小问题之后,在每个子问题中解决问题需求
  3. 归并:把问题解决完之后,将子问题进行合并。

接下来,我们就来通过一些练习来加深对分治思想的理解。

75. 颜色分类

算法分析

这道题的话就是要求我们将0、1、2这三个数依次从小排到大,那么对于这道题的话,其实我们有好几种排序方法都可以解决这道题,甚至我们可以使用java中的Arrays.sort()方法都可以解决,但是这里是不允许的。我们这里可以使用分治的思想来解决这道题。

算法步骤

算法代码

class Solution {/*** 交换数组中的两个元素* * @param arr 数组* @param left 左侧元素的索引* @param right 右侧元素的索引*/public void swap(int[] arr, int left, int right) {int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;}/*** 对颜色进行排序,将0放到数组的左边,2放到数组的右边,1保持原位* * @param nums 需要排序的颜色数组,其中的颜色用0、1、2表示*/public void sortColors(int[] nums) {int n = nums.length;int i = 0, left = -1, right = n;// 遍历数组,根据元素的值进行交换,最终达到0在左边,2在右边的目的while (i < right) {if (nums[i] == 0) {swap(nums, i++, ++left);} else if (nums[i] == 2) {swap(nums, i, --right);} else {i++;}}}
}

时间复杂度为O(n),空间复杂度为O(1). 

912. 排序数组 - 力扣(LeetCode)

算法分析

对于这种排序的题目,其实我们有很多种排序的方法可以解决,但是我们这里只讲如何使用分治的思想来解决这些排序题。 

算法步骤

对于这道题,我们可以采用分治的思想来解决,将数组划分为n个子数组,并且在n个子数组中使用类似快排的步骤来进行排序。同时我们需要注意:快排在趋近有序的情况下的时间复杂度为O(n^2),所以我们可以采用优化方法,如三数取中法,随机取值方法,这里我们采用的是随机取值法,使得算法的时间步骤度降为O(N*logN)

算法代码

/*** Solution 类用于提供一种基于快速排序的数组排序解决方案*/
class Solution {/*** 对数组进行快速排序* * @param nums 待排序的整数数组* @return 排序后的数组*/public int[] sortArray(int[] nums) {qsort(nums, 0, nums.length - 1);return nums;}/*** 交换数组中两个指定位置的元素* * @param nums 整数数组* @param left 左侧位置索引* @param right 右侧位置索引*/public void swap(int[] nums, int left, int right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}/*** 使用快速排序算法对数组进行排序* * @param nums 待排序的整数数组* @param left 排序开始的左边界索引* @param right 排序结束的右边界索引*/public void qsort(int[] nums, int left, int right) {if (left >= right) return;int key = nums[new Random().nextInt(right - left + 1) + left];int i = left, L = left - 1, R = right + 1;while (i < R) {if (nums[i] < key) swap(nums, ++L, i++);else if (nums[i] == key) i++;else swap(nums, i, --R);}qsort(nums, left, L);qsort(nums, R, right);}
}

215. 数组中的第K个最大元素 - 力扣(LeetCode)

算法分析

这道题其实就是TOP-K问题,我们可以使用优先级队列(堆)的方法来解决这个问题:首先我们可以创建一个小根堆,在这个小根堆中放入k个元素,接着遍历剩余的n-k个元素,查看堆顶元素是不是小于数组中的元素,若小于则进行替换。当然,我们这里主要讲分治思想,那么我们同样是利用快排来解决这道题。

算法步骤

算法代码

/*** Solution类用于解决寻找数组中第k大的元素的问题*/
class Solution {/*** 寻找数组中第k大的元素* * @param nums 输入的整数数组* @param k 指定的第k大元素* @return 数组中第k大的元素*/public int findKthLargest(int[] nums, int k) {// 调用快速排序相关函数来寻找第k大的元素return qsort(nums, 0, nums.length - 1, k);}/*** 快速排序算法的实现,用于寻找第k大的元素* * @param nums 输入的整数数组* @param l 排序区间的左边界* @param r 排序区间的右边界* @param k 指定的第k大元素* @return 第k大的元素*/private int qsort(int[] nums, int l, int r, int k) {// 如果左右指针相遇,直接返回该位置的元素if(l == r) return nums[l];// 随机选择一个基准值int key = nums[new Random().nextInt(r - l + 1) + l];int left = l - 1, right = r + 1, i = l;// 分区过程,将数组分为三部分:小于基准值的、等于基准值的和大于基准值的while(i < right) {if(nums[i] < key) swap(nums, ++left, i++);else if(nums[i] > key) swap(nums, i, --right);else i++;}// 根据分区结果,决定下一步的查找范围int b = right - left - 1; // 等于基准值的区域大小int c = r - right + 1; // 大于基准值的区域大小if(c >= k) return qsort(nums, right, r, k); // 如果第k大在大于基准值的区域else if(b + c >= k) return key; // 如果第k大在等于基准值的区域return qsort(nums, l, left, k - b - c); // 否则在小于基准值的区域继续查找}/*** 交换数组中两个元素的位置* * @param nums 输入的整数数组* @param i 第一个元素的索引* @param j 第二个元素的索引*/private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

LCR 159. 库存管理 III - 力扣(LeetCode)

算法分析

本道题其实与前面的找第k个最大元素类似,我们依旧可以使用排序,然后有另一个数组记录[0,k]期间的数,但本道题我们可以采用分治的思想,利用快排来解决。

算法步骤

当我们完成上述的过程后,我们需要利用一个大小为k的数组ret来接收nums数组中【0,k】区间的数.

算法代码

class Solution {/*** 库存管理函数,通过快速排序算法对库存进行管理** @param stock 库存数据数组* @param cnt 需要管理的库存项数量* @return 管理后的库存数组*/public int[] inventoryManagement(int[] stock, int cnt) {// 使用快速排序对库存数组进行排序qsort(stock, 0, stock.length - 1, cnt);// 创建一个新的数组来存储管理后的库存数据int[] ret = new int[cnt];// 将排序后的库存数据的前cnt个元素复制到新的数组中for(int i=0;i<cnt;i++) {ret[i] = stock[i];}// 返回管理后的库存数组return ret;}/*** 交换数组中两个元素的位置** @param nums 数组* @param left 左侧元素索引* @param right 右侧元素索引*/public void swap(int[] nums, int left, int right){int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}/*** 快速排序算法的实现** @param nums 待排序的数组* @param left 排序开始的左侧索引* @param right 排序结束的右侧索引* @param k 需要管理的库存项数量,用于决定排序的范围*/private void qsort(int[] nums, int left, int right, int k){if(left >= right) return;int key = nums[new Random().nextInt(right - left + 1) + left];int i = left, L = left - 1, R = right + 1;while(i < R){if(nums[i]<key) swap(nums,++L,i++);else if(nums[i]==key) i++;else swap(nums,i,--R);}// 根据分区结果,决定下一步的查找范围int a=L-left+1;int b=R-L-1;if(a>=k) qsort(nums,left,L,k);else if(a+b>=k) return;else qsort(nums,R,right,k-a-b);}
}

以上就是采用分治思想使用快排的一些题目。

本篇就先到这里啦~下一篇将为大家讲解采用归并排序如何解决一些算法题目。

若有不足,欢迎指正~

 

相关文章:

【算法专场】分治(上)

目录 前言 什么是分治&#xff1f; 75. 颜色分类 算法分析 算法步骤 算法代码 912. 排序数组 - 力扣&#xff08;LeetCode&#xff09; 算法分析 算法步骤 算法代码 215. 数组中的第K个最大元素 - 力扣&#xff08;LeetCode&#xff09; 算法分析 算法步骤 ​编辑…...

腾讯云软件工程师面试问题收集记录-数据库

SQL是什么&#xff1a;结构化查询语言&#xff0c;是一种专门用于管理关系型数据库管理系统的编程语言 MySQL操作命令 数据库操作 登陆数据库&#xff1a;mysql -u 用户面 -p创建数据库&#xff1a;CREATE DATABASE testdb; SQLite操作命令 数据库操作 创建数据库&#xff1a;…...

Sourcetree安装教程及使用

下载链接&#xff1a;源代码树 |适用于 Mac 和 Windows 的免费 Git GUI (sourcetreeapp.com) Sourcetree安装教程及使用_sourcetree 安装使用-CSDN博客...

TryHackMe 第1天 | Introduction to Cyber Security

偶然之间了解到了TryHackMe这个网站&#xff0c;尝试跟着其中的学习路径进行学习&#xff0c;发现还是挺适合入门网络安全这一领域的。但是这个网站包含了很多内容&#xff0c;如果不用一些东西记录下来&#xff0c;那么很容易忘记&#xff0c;所以打算在此记录一下学习过程。 …...

ASP.NET MVC 迅速集成 SignalR

在现代 Web 应用程序中&#xff0c;实时更新数据是一个常见需求。本文将详细介绍如何在 ASP.NET MVC 项目中使用 SignalR 实现定时任务操作数据库并将数据更新到网页。我们将逐步讲解如何配置 SignalR、创建定时任务、操作数据库以及在前端显示实时数据。 目录 项目初始化安装…...

[数据集][目标检测]葡萄成熟度检测数据集VOC+YOLO格式1123张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1123 标注数量(xml文件个数)&#xff1a;1123 标注数量(txt文件个数)&#xff1a;1123 标注…...

【Python 数据分析学习】Matplotlib 的基础和应用

题目 1 Matplotlib 主要特性2 Matplotlib 基础知识2.1 导入模块2.2 图形构成2.2.1 图形&#xff08;Figure&#xff09;2.2.2 轴 &#xff08;Axes&#xff09;2.2.3 轴线&#xff08;axis&#xff09; 2.5 中文设置2.5.1 借助rcParams修改字体实现设置2.5.2 增加一个fontprope…...

HarmonyOS应用开发者基础认证

目录 一、判断二、单选三、多选 一、判断 1、HarmonyOS提供了基础的应用加固安全能力&#xff0c;包括混淆、加密和代码签名能力。正确 2、可以通过ohpm uninstall 指令下载指定的三方库。错误 3、支持模块化开发是指一个应用通常会包含多种功能&#xff0c;将不同的功能特性…...

gin基本使用

中文文档:https://gin-gonic.com/zh-cn/docs/ 下载和安装gin模块 go get -u github.com/gin-gonic/gin简单接口demo package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default() // 创建一个默认的路由引擎r.GET("/pin…...

【VUE】pinia持久化存储

前言&#xff1a;状态持久化存储的意义在于它能够确保用户在与应用程序交互时&#xff0c;其操作状态、用户偏好、应用数据等关键信息在页面刷新、浏览器关闭或重新启动后依然得以保留&#xff0c;从而提供连贯、无缝的用户体验&#xff0c;避免因状态丢失导致的不便和重复操作…...

【Java基础】泛型

文章目录 泛型一、概述二、泛型的使用1、类2、方法3、接口 三、泛型通配符1、<?>2、<? extends T>3、<? super T> 四、泛型的擦除1、泛型的擦除2、泛型边界的擦除3、无法实例化泛型类型 泛型 一、概述 泛型&#xff08;Generic&#xff09;是一种机制&a…...

STL-vector练习题

118. 杨辉三角 思路&#xff1a; 杨辉三角有以下性质使我们要用到的&#xff1a; ● 每行数字左右对称&#xff0c;由 1 开始逐渐变大再变小&#xff0c;并最终回到 1。 ● 第 n 行&#xff08;从 0 开始编号&#xff09;的数字有 n1 项&#xff0c;前 n 行共有 2n(n1)个数。…...

Leetcode 165. 比较版本号(Medium)

给你两个 版本号字符串 version1 和 version2 &#xff0c;请你比较它们。版本号由被点 . 分开的修订号组成。修订号的值 是它 转换为整数 并忽略前导零。 比较版本号时&#xff0c;请按 从左到右的顺序 依次比较它们的修订号。如果其中一个版本字符串的修订号较少&#xff0c…...

Android 12 Launcher3 去掉Hotseat

1.概述 在12.0 产品定制化开发中 由产品需求Launcher3 页面布局的原因&#xff0c;要求Launcher3 需要去掉Hotseat 不显示Hotseat下面几个图标&#xff0c;而做满屏app的显示&#xff0c;从而达到美观的效果&#xff0c;下面就来分析去掉Hotseat从而实现这个功能 2.Launcher3 …...

Nginx实用篇:实现负载均衡、限流与动静分离

Nginx实用篇&#xff1a;实现负载均衡、限流与动静分离 | 原创作者/编辑&#xff1a;凯哥Java | 分类&#xff1a;Nginx学习系列教程 Nginx 作为一款高性能的 HTTP 服务器及反向代理解决方案&#xff0c;在互联网架构中扮演着至关重要的角色。它…...

python | Python中的类多态:方法重写和动态绑定

本文来源公众号“python”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Python中的类多态&#xff1a;方法重写和动态绑定 多态&#xff08;Polymorphism&#xff09;是面向对象编程的核心特性之一&#xff0c;它允许同一接口在…...

Rust编写Windows服务

文章目录 Rust编写Windows服务一&#xff1a;Windows服务程序大致原理二&#xff1a;Rust中编写windows服务三&#xff1a;具体实例 Rust编写Windows服务 编写Windows服务可选语言很多, 其中C#最简单。本着练手Rust语言&#xff0c;尝试用Rust编写一个服务。 一&#xff1a;Win…...

MATLAB 从 R2024B 开始支持树莓派 5

树莓派&#xff08;Raspberry Pi&#xff09;系列是一系列基于单板计算机的微型电脑&#xff0c;由英国的树莓派基金会于 2012 年开始发布。它的目标是提供一个低成本、易于学习和玩耍的平台&#xff0c;用于教育和初学者学习计算机科学和编程。 目前市面上&#xff0c;最新最…...

MiniBlogum项目简介

MiniBlogum项目简介 文章目录 MiniBlogum项目简介一、引言二、技术栈与开发环境三、主要功能&#xff08;一&#xff09;用户注册与登录&#xff08;二&#xff09;查看当前登录用户/作者头像、昵称、Gitee仓库地址&#xff08;三&#xff09;查看博客列表&#xff08;四&#…...

如何用 OBProxy 实现 OceanBase 的最佳路由策略

引言 OBProxy&#xff0c;即OceanBase Database Proxy&#xff0c;也简称为ODP&#xff0c;是 OceanBase数据库的专属服务代理。通过应用OBProxy&#xff0c;由后端OceanBase集群的分布式特性所带来的复杂性得以屏蔽&#xff0c;从而使得访问分布式数据库的体验如同访问单机数…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...