2.4.快速排序——先分区再递归,为什么它平均这么快却可能退化?

news2026/4/3 21:13:48
2.4.快速排序——先分区再递归为什么它平均这么快却可能退化系列搜索与排序 | 第 4 篇共 16 篇难度⭐⭐⭐☆☆ 中等标签排序快速排序分治随机化三路快排上一篇2.3.插入排序——像打牌一样整理数组为什么它对“几乎有序”数据特别友好下一篇2.5.归并排序——分而治之再合而并为什么它能稳定保持 O(n log n)前言学完前三篇基础排序后很多人会立刻问一个问题明明已经有了冒泡、选择、插入为什么后面还要单独学快速排序为什么很多面试里手写排序题第一反应也是快排它平均很快那到底快在哪里既然它最坏会退化到O(n²)为什么还敢大规模使用快速排序的魅力就在这里它不是“理论上最稳”的排序但经常是“实践里最快、最顺手、最值得掌握”的排序。快速排序的核心不在“交换得多漂亮”而在于通过一个基准值pivot把数组分成两边让左边都不大于它右边都不小于它然后只递归处理左右两个子问题这篇就把快速排序真正讲透它的分区过程到底在做什么为什么平均复杂度是O(n log n)为什么最坏会掉到O(n²)随机化、三路快排、小区间优化分别解决什么问题它和归并排序、堆排序到底该怎么选一、算法思想先选基准再把数组一分为二快速排序的核心思想可以浓缩成一句话找一个基准元素把数组按它切成左右两边然后递归处理左右两边。设基准值是pivot一次分区完成后数组会满足pivot左边的元素都 pivotpivot右边的元素都 pivotpivot自己已经处在最终正确位置上于是问题自然变成两个更小的子问题对左半部分继续快排对右半部分继续快排这就是典型的分治法。和归并排序相比它们都属于分治但思路不同归并排序先递归排好左右两边再把两个有序部分合并起来快速排序先通过分区把一个元素放到正确位置再递归处理左右两边也就是说归并排序的关键动作是合并快速排序的关键动作是分区核心不变量每次partition()结束后基准值两侧的元素虽然不一定各自完全有序但一定已经满足“左边不大于它、右边不小于它”。二、完整图解过程以数组[5, 3, 8, 1, 2, 7]为例演示最常见的写法选择最右元素7作为pivot第 1 步扫描一遍把小于等于7的元素往左放这里最容易绕晕的点是到底是谁在动怎么动为什么8会被一点点“挤”到后面去可以先记住两个指针j扫描指针从左到右依次检查每个元素i边界指针表示“当前最后一个 pivot的位置”初始时i -1表示左边还没有任何一个元素被确认放好。初始状态[5, 3, 8, 1, 2, 7] ↑ pivot7接下来让j从左往右扫描[5, 3, 8, 1, 2]规则只有一条只要发现nums[j] pivot就先把i往右扩一格再把nums[j]交换到这个新位置上。也就是说不是专门去“搬大数”而是不断把“小于等于 pivot 的数”塞进左侧合格区。扫描位置j当前值动作数组状态初始-i -1左侧合格区为空[5, 3, 8, 1, 2, 7]j 055 7i - 0交换nums[0]和nums[0][5, 3, 8, 1, 2, 7]j 133 7i - 1交换nums[1]和nums[1][5, 3, 8, 1, 2, 7]j 288 7不交换i不变[5, 3, 8, 1, 2, 7]j 311 7i - 2交换nums[2]和nums[3][5, 3, 1, 8, 2, 7]j 422 7i - 3交换nums[3]和nums[4][5, 3, 1, 2, 8, 7]这时候扫描结束i 3说明下标0 ~ 3的位置都已经是 7的元素8之所以跑到后面不是我们主动“把它搬走”而是因为1、2这两个更小的数先后插进了左侧区域把它挤到了右边最后一步再把pivot7和nums[i 1]交换也就是和8交换[5, 3, 1, 2, 8, 7] ↑ i1交换后[5, 3, 1, 2, 7, 8] ↑ pivot 已就位现在基准值7的位置已经确定了左边都 7右边都 7你可以把这一轮分区理解成一句话扫描指针j负责找“小数”边界指针i负责给“小数”腾位置扫描结束后再把pivot塞进左右分界点。第 2 步递归处理左半部分[5, 3, 1, 2]继续选最右元素2为基准[5, 3, 1, 2] ↑ pivot2分区后[1, 2, 5, 3] ↑ pivot 已就位于是继续递归左边[1]不用排右边[5, 3]继续排第 3 步处理[5, 3]选3为基准[5, 3] - [3, 5]这时整个数组变成[1, 2, 3, 5, 7, 8]排序完成。✅整体过程汇总阶段操作结果初始分区以7为基准分区[5, 3, 1, 2, 7, 8]递归左侧以2为基准分区[1, 2, 5, 3]继续递归排[5, 3][3, 5]全部完成左右子问题都解决[1, 2, 3, 5, 7, 8]三、代码实现在看代码前先把上面的图解和下面的模板对齐一下图解里为了方便理解直接固定取最右边的7作为pivot代码里为了更实战先随机选一个pivot_idx再把它交换到right位置所以随机化只影响“选谁当基准”不影响后面的分区动作真正进入扫描阶段后依然可以把它理解成“拿最右元素当pivot”对应关系是这样的图解里的扫描指针j↔ 代码里的for j in range(left, right)图解里的边界指针i↔ 代码里的i left - 1图解里“发现 pivot的数就扩边界并交换” ↔ 代码里的if nums[j] pivot: i 1; nums[i], nums[j] nums[j], nums[i]图解里“扫描结束后把pivot放到分界点” ↔ 代码里的nums[i 1], nums[right] nums[right], nums[i 1]如果代入上面那个例子第一次分区刚好就是left 0, right 5pivot 7i初始为-1j依次扫描0 ~ 4也就是说上面的图解和下面这份代码在分区逻辑上是一一对应的只是代码额外多了一步“随机选基准再换到最右边”。Python 版本随机化快排importrandomdefquick_sort(nums):defpartition(left,right):pivot_idxrandom.randint(left,right)nums[pivot_idx],nums[right]nums[right],nums[pivot_idx]pivotnums[right]ileft-1forjinrange(left,right):ifnums[j]pivot:i1nums[i],nums[j]nums[j],nums[i]nums[i1],nums[right]nums[right],nums[i1]returni1defsort(left,right):ifleftright:returnmidpartition(left,right)sort(left,mid-1)sort(mid1,right)ifnums:sort(0,len(nums)-1)returnnums nums[5,3,8,1,2,7]print(quick_sort(nums))# [1, 2, 3, 5, 7, 8]这个版本比“固定选最右边元素”更实战因为遇到本来有序、逆序、特殊构造数据时随机化能显著降低退化到O(n²)的概率C 版本#includeiostream#includevector#includecstdlib#includectimeusingnamespacestd;intpartition(vectorintnums,intleft,intright){intpivotIdxleftrand()%(right-left1);swap(nums[pivotIdx],nums[right]);intpivotnums[right];intileft-1;for(intjleft;jright;j){if(nums[j]pivot){i;swap(nums[i],nums[j]);}}swap(nums[i1],nums[right]);returni1;}voidquickSort(vectorintnums,intleft,intright){if(leftright){return;}intmidpartition(nums,left,right);quickSort(nums,left,mid-1);quickSort(nums,mid1,right);}intmain(){srand((unsigned)time(nullptr));vectorintnums{5,3,8,1,2,7};quickSort(nums,0,(int)nums.size()-1);for(intx:nums){coutx ;}return0;}四、复杂度分析情况时间复杂度原因最好情况O(n log n)每次分区都比较均衡递归树高度约为log n平均情况O(n log n)随机化后大多数情况下都比较均衡最坏情况O(n²)每次都极不均衡比如一边空、一边剩下n-1个元素空间复杂度O(log n)主要来自递归栈极端退化时可能达到O(n)稳定性❌ 不稳定分区交换会打乱相等元素的原始相对顺序为什么平均是O(n log n)因为每一层分区都会把当前区间扫描一遍总代价接近O(n)如果每次都能把问题切得比较平衡层数大约是log n于是总复杂度就是每层 O(n) × 层数 O(log n) O(n log n)对应递推式可以写成T(n) T(k) T(n-k-1) O(n)当k大致接近n/2时就接近O(n log n)当k总是0或n-1时就会退化成O(n²)。五、为什么它平均很快但最坏会退化快速排序“快”的核心不只是复杂度写成了O(n log n)而是它在工程上还有三个很讨喜的特点1原地排序额外空间小和归并排序不同快排通常不需要额外开一个O(n)的辅助数组。这意味着内存压力更小元素移动更贴近原数组常数往往更好看2局部性好缓存友好分区过程基本是在一段连续内存里扫描和交换缓存命中率通常不错。3子问题独立递归结构自然一次分区以后左边区间自己排右边区间自己排问题结构很干净。但它的风险也很明显为什么会退化到O(n²)如果你每次都选到了极差的pivot比如已升序数组里总选最后一个数已降序数组里总选第一个数那么每次只确定 1 个元素位置剩下几乎全部元素还在同一侧。递归会变成n (n-1) (n-2) ... 1 O(n²)所以快排真正要学的不只是“会写”而是会防退化。六、优化与变体优化 1随机化 pivot这是最常见、最实用的一种优化。做法很简单在当前区间里随机抽一个位置把它交换到末尾再按普通方式做分区好处是极端输入不容易稳定卡你平均表现更稳优化 2三路快排如果数组里有很多重复元素普通二路分区会比较吃亏。例如[5, 5, 5, 5, 5, 5, 5]这时反复分区其实很浪费。三路快排会把数组一次分成三部分 pivot pivot pivot这样中间那一整段都不用再递归。defquick_sort_3way(nums,left,right):ifleftright:returnpivotnums[left]ltleft ileft1gtrightwhileigt:ifnums[i]pivot:nums[lt],nums[i]nums[i],nums[lt]lt1i1elifnums[i]pivot:nums[i],nums[gt]nums[gt],nums[i]gt-1else:i1quick_sort_3way(nums,left,lt-1)quick_sort_3way(nums,gt1,right)优化 3小区间切换插入排序当区间已经很小时继续递归快排未必划算。常见做法如果子数组长度小于某个阈值如 16就直接改用插入排序这是因为小数组上插入排序常数很小代码简单能减少递归调用开销变体快速选择Quickselect快排的分区思想还能直接拿来求第k小第k大中位数因为每次分区后pivot的最终排名已经确定了。如果我们只关心“第k个位置”就只需要递归进入一侧而不是两边都递归。这就是Quickselect。七、与归并排序、堆排序对比对比项快速排序归并排序堆排序平均时间复杂度O(n log n)O(n log n)O(n log n)最坏时间复杂度O(n²)O(n log n)O(n log n)空间复杂度O(log n)O(n)O(1)稳定性不稳定稳定不稳定工程常用度很高很高中等典型优势平均快、常数小上界稳、适合链表原地且最坏也稳典型短板会退化额外空间大常数和局部性一般一句话记忆快排平均最快最常用但要防退化归并时间上界稳适合稳定排序与链表堆排空间最省最坏情况也稳但手感通常不如前两者八、OJ 例题讲解例题 1HDU 1040 — As Easy As AB可直接套裸快排模板题目来源HDU题号 1040难度⭐⭐☆☆☆ 简单题目链接http://acm.hdu.edu.cn/showproblem.php?pid1040题目描述(这道题眼熟不前面用过就拿来练裸排序用)给出多组整数序列请你把每组数据按升序输出。关键数据范围第一行输入测试组数T每组数据满足1 N 1000每组都要完整输出排好序的序列为什么这题适合放在快排章节因为它就是很纯粹的“排序模板落地题”题意没有额外陷阱就是老老实实把数组排好数据规模不大直接套前面的裸快排模板就能通过很适合第一次把partition quickSort真正写进 OJ解题思路每组数据单独读入一个数组直接套用前文的随机化二路快排模板排序完成后按题目要求输出即可C 解法随机化快排模板#includebits/stdc.husingnamespacestd;intpartition(vectorintnums,intleft,intright){intpivotIdxleftrand()%(right-left1);swap(nums[pivotIdx],nums[right]);intpivotnums[right];intileft-1;for(intjleft;jright;j){if(nums[j]pivot){i;swap(nums[i],nums[j]);}}swap(nums[i1],nums[right]);returni1;}voidquickSort(vectorintnums,intleft,intright){if(leftright){return;}intmidpartition(nums,left,right);quickSort(nums,left,mid-1);quickSort(nums,mid1,right);}intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);intT;cinT;while(T--){intn;cinn;vectorintnums(n);for(inti0;in;i){cinnums[i];}if(n1){quickSort(nums,0,n-1);}for(inti0;in;i){if(i){cout ;}coutnums[i];}cout\n;}return0;}这题适合拿来练什么练最标准的“裸快排模板”怎么直接套到 OJ练partition(left, right)这一段的扫描与交换逻辑练多组输入下如何把算法模板写成完整可提交代码例题 2LeetCode 215 — 数组中的第 K 个最大元素Quickselect 经典题题目来源LeetCode题号 215难度⭐⭐⭐☆☆ 中等题目链接https://leetcode.cn/problems/kth-largest-element-in-an-array/题目描述给定整数数组nums和整数k返回数组中第k个最大的元素。关键数据范围1 k nums.length 10^5-10^4 nums[i] 10^4为什么这题和快排强相关因为你根本不需要把整个数组都排完。只要每次分区后判断pivot所在分块是否已经覆盖目标排名目标下标是在左半边还是右半边就能只继续处理一侧把平均复杂度压到O(n)。这题为什么不能直接照搬前面的单指针模板因为这题会卡“大量重复元素”的情况。比如数组全是1时如果还用前面那种 Lomuto 单指针分区每次分区都会把区间切得非常不均匀很可能一次只缩掉一个位置Quickselect就会被拖慢最终超时所以这题更稳的写法是随机化选pivot 双指针。核心代码C Quickselect 双指针优化classSolution{public:intpartition(vectorintnums,intleft,intright){intpivotnums[leftrand()%(right-left1)];intileft-1;intjright1;while(ij){do{i;}while(nums[i]pivot);do{j--;}while(nums[j]pivot);if(ij){swap(nums[i],nums[j]);}}returnj;}intfindKthLargest(vectorintnums,intk){inttargetk-1;intleft0;intright(int)nums.size()-1;while(leftright){intmidpartition(nums,left,right);if(targetmid){rightmid;}else{leftmid1;}}returnnums[left];}};为什么双指针版更稳左指针找“应该去右边”的数右指针找“应该去左边”的数两个指针相向而行重复元素会自然分散到两边即使数据像[1,1,1,1,1,...]这样极端分区也不会老是只缩一个点这题非常适合体会快排不只是排序算法还是选择算法而同样是分区面对重复元素时分区写法本身也会决定你能不能过题。例题 3LeetCode 75 — 颜色分类三路划分典型题题目来源LeetCode题号 75难度⭐⭐⭐☆☆ 中等题目链接https://leetcode.cn/problems/sort-colors/题目描述给定一个只包含0、1、2的数组对它们进行原地排序。关键数据范围1 nums.length 300nums[i]只能是0、1、2为什么这题放在快排章节很合适因为它的最优思路其实就是“三路划分”。虽然这题不需要真的写完整快排但它和三路快排共享同一个核心思想小的放左边等于的放中间大的放右边C 解法荷兰国旗问题classSolution{public:voidsortColors(vectorintnums){intleft0;inti0;intright(int)nums.size()-1;while(iright){if(nums[i]0){swap(nums[left],nums[i]);left;i;}elseif(nums[i]2){swap(nums[i],nums[right]);right--;}else{i;}}}};这题适合用来加深对“三路分区”的理解。九、适用场景场景是否适合原因通用数组排序✅平均性能强工程表现通常很好需要原地排序✅额外空间通常只要递归栈数据规模较大✅随机化后平均效率高重复元素很多✅用三路快排更合适需要稳定排序❌快排天然不稳定必须保证最坏时间上界⚠️单纯快排不稳需额外防退化或换算法十、常见错误总结错误原因正确做法递归边界写错没有在left right时返回先判断区间长度是否合法分区后递归区间写错把pivot位置又递归进去递归[left, mid-1]和[mid1, right]固定选端点导致退化遇到有序数组容易被卡优先随机化或三数取中误以为快排稳定交换会打乱相等元素顺序明确记住快排不稳定大量重复元素仍用普通二路分区递归效率变差考虑三路快排求第 k 大时还把整个数组全排完没利用分区排名信息改用 Quickselect总结要点内容核心思想选pivot分区后递归处理左右子数组平均复杂度O(n log n)最坏复杂度O(n²)空间复杂度O(log n)平均稳定性❌ 不稳定核心优势原地、平均快、工程常用主要短板可能退化需要防最坏情况一句话记住它快速排序不是靠“合并”取胜而是靠一次次高质量分区把无序问题快速切碎。上一篇2.3.插入排序——像打牌一样整理数组为什么它对“几乎有序”数据特别友好下一篇2.5.归并排序——分而治之再合而并为什么它能稳定保持 O(n log n)看完有收获的话点个赞再走有问题欢迎评论区讨论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2480108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…