Swift 解锁 LeetCode 热门难题:不改数组也能找出重复数字?

article/2025/8/22 21:35:17

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 解读:
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结
    • 实际场景类比
    • 可运行 Demo(Swift Playground)
    • 未来展望

摘要

在数组中找出唯一的重复数字,听起来像一道简单的题目,但如果你不能修改原数组、不能使用额外空间,挑战就变得很有意思了。本文通过 Swift 实现 LeetCode 第 287 题《寻找重复数》的题解,并结合实际编码场景详细拆解背后的逻辑推理过程,帮你真正掌握这道经典的算法题。

描述

题目要求你在一个包含 n + 1 个整数的数组中找到一个重复的数。这些数的取值范围是 [1, n],而且保证 只有一个数字重复,可能重复多次

但它还加了一些限制:

  • 数组不能修改(也就是只读)
  • 空间复杂度得是常数级 O(1)
  • 尽可能做到时间复杂度为线性 O(n)

看起来挺棘手?别急,下面我们一步一步来拆解。

题解答案

常见的思路有三种:

  1. 暴力法 / 哈希法(不能用,违反空间复杂度)
  2. 排序 + 遍历(不能用,违反不能修改数组)
  3. 快慢指针(可以用,经典的“链表找环”变体)

我们要用的是第三种方法,也叫 Floyd 判圈算法。

思路是把数组元素看成指针,nums[i] 代表指向下一个元素的索引,就像一个链表。如果有重复数字,就一定会有一个“环”。

题解代码分析

func findDuplicate(_ nums: [Int]) -> Int {var slow = nums[0]var fast = nums[0]// 第一阶段:找相遇点repeat {slow = nums[slow]fast = nums[nums[fast]]} while slow != fast// 第二阶段:找入口(重复的数字)slow = nums[0]while slow != fast {slow = nums[slow]fast = nums[fast]}return slow
}

解读:

  • 第一次 while 循环找的是两个指针在环里相遇的那个位置。我们先从 nums[0] 开始,slow 每次走一步,fast 每次走两步,像跑圈一样,最终肯定会在环里相遇。
  • 第二次 while 循环是经典的“找环入口”,我们让一个指针从开头出发,另一个从相遇点出发,每次走一步,再次相遇的点就是重复数字。

示例测试及结果

let test1 = [1, 3, 4, 2, 2]
print(findDuplicate(test1))  // 输出: 2let test2 = [3, 1, 3, 4, 2]
print(findDuplicate(test2))  // 输出: 3let test3 = [3, 3, 3, 3, 3]
print(findDuplicate(test3))  // 输出: 3

无论重复的是谁,只要有重复,这个算法就能找出来,效率也很高。

时间复杂度

  • 整体是 O(n),因为我们最多只跑两次遍历,而且每次最多走 n 步。

空间复杂度

  • O(1),只用了两个变量 slowfast,没有开任何额外空间。

总结

这题乍一看像是“简单查重”,实则考验对链表结构与指针遍历逻辑的理解。如果你碰到限制不能修改数组、不能用额外空间的情况,这种借助“指针构造隐含链表”的技巧就非常值得掌握。

而且这种技巧在很多系统设计里也很实用,比如检测日志流的循环引用、追踪用户路径中的重复操作等等。

实际场景类比

想象一下你在做用户路径分析,用户访问路径用数组表示 [页面1, 页面2, 页面3, 页面2, 页面4],你希望知道哪个页面用户又返回访问了。

你不能改动原始日志(只读),也不能复制一份数据再做处理(节省内存),这时候就可以考虑类似的“快慢指针找环”方式来识别重复跳转的路径。

可运行 Demo(Swift Playground)

import Foundationfunc findDuplicate(_ nums: [Int]) -> Int {var slow = nums[0]var fast = nums[0]repeat {slow = nums[slow]fast = nums[nums[fast]]} while slow != fastslow = nums[0]while slow != fast {slow = nums[slow]fast = nums[fast]}return slow
}let sample = [1, 4, 6, 2, 5, 3, 6]
print("重复数字是:\(findDuplicate(sample))")

未来展望

这个题是很多“限制场景下查重”的代表题,我们可以往更复杂的方向去探索:

  • 如何在海量数据(分布式系统)中查找重复?
  • 如果有多个重复的数字,又该如何扩展这类算法?
  • Swift 中的指针式遍历,还有哪些地方能发挥类似作用?

http://www.hkcw.cn/article/ewMtyQydXX.shtml

相关文章

防范DDoS攻击,服务器稳定性崩溃的根源与高效防御对策

DDoS攻击(分布式拒绝服务攻击)已成为危害服务器稳定性和业务连续性的主要因素之一。本文将深入探讨为什么服务器一遇到DDoS攻击就崩溃,以及如何从根本上实现有效防御和应对这一威胁,帮助企业提升网络安全水平。 具体内容如下&…

女农机手再度为困难农户收麦 跨省公益收割500亩

姜晓娜曾是一名美甲师,如今她已成为一名熟练的农机手,驾驶着3米高的收割机在麦田劳作。她的态度认真,不敷衍、不马虎,赢得了“干得好、割得快、不撒粮、长得俊”的评价。这些夸奖和赞美是她前进的动力。河南省是我国粮食大省,5月24日至28日,姜晓娜和弟弟在河南平顶山、驻…

iVX 如何用 VL 中间语言构建程范式闭环?

一、技术定位:VL 中间语言的「三位一体」技术闭环 在数字化转型浪潮中,iVX 自主研发的 VL(Visual Language)中间语言体系,正通过 "可视化建模→VL 编译→多语言生成" 的技术闭环,重新定义图形化…

今日行情明日机会——20250529

上证指数放量收阳线,个股涨多跌少,汽车主线方向凸显。 深证指数放量收阳线,可以围绕主线方向做。 2025年5月29日涨停股主要行业方向分析 1. 智能驾驶(政策场景商业化突破) 涨停家数:24家。 代表标…

Arduino门禁系统:RFID-RC522卡验证与LED、0.96OLED(IIC)的门禁场景

引言 在物联网和智能家居日益普及的今天,门禁系统作为安全防护的第一道关卡,有着广泛的应用需求。本文将介绍如何利用 Arduino Uno 开发板,结合 0.96 寸 OLED 显示屏、RC522 RFID 模块以及红绿 LED 灯,搭建一个简易的门禁系统&am…

各地狂建学职业本科成香饽饽,职业本科怎么就成了香饽饽?

各地狂建学职业本科成香饽饽。毕业季,当许多高校学生还在忙着找工作时,西安汽车职业大学2023届智能制造工程学院的毕业生乔延哲,在6月离校前就拿到了10余个Offer,被多家企业争抢,而类似的例子还有许多。大众在不解的同时也感叹,职业本科怎么就成了香饽饽?2025年了,各地…

【电路笔记 TMS320F28335DSP】McBSP 从源时钟得到 生成时钟 CLKG 帧同步信号 FSG

对应于原文 Multichannel Buffered Serial Port (McBSP)的 2.5.3 Data Clock Generation。 CLKG Figure 2-4. Sample Rate Generator Block Diagram CLKG 是采样率发生器输出的数据位时钟(Data Bit Clock),它被用来控制: 数据发…

校园演出该不该“外包”,节目竞演变花钱比拼?

校园演出该不该“外包”。学校艺术汇演、节目表演本是展示学生风采、锻炼孩子能力的重要契机。然而当下,节目编排“外包”现象却开始冒头,有的班级“高价请老师”“花钱买节目”,引发家长质疑。半月谈记者调查了解到,当前部分校园艺术节目排练评比压力大、艺术教育依赖外包…

寄存器模型2

6.MCDF寄存器设计代码 (1)示意图 (2)代码 verilog中数组操作:regs[SLV0_RW_REG][0:5]指的是32bit数据下的0:5位。 7.adapter (1)adapter的位置 (2)adapter实现 &#…

胡塞武装称过去一周对以色列多地目标实施打击

当地时间5月29日晚,也门胡塞武装领导人阿卜杜勒马利克胡塞在其每周讲话中表示,在本周内,该组织对以色列多地目标实施了军事打击。在打击过程中,该组织使用了14枚高超音速导弹、弹道导弹以及无人机,打击目标包括以色列特拉维夫以北的雅法、海法、南部城市阿什凯隆以及红海沿…

女子向丈夫要5元遭拒轻生?假 网传信息不实

近日,网上流传一则消息称山东一名女子因向丈夫索要5元钱买煎饼果子当早餐被拒后选择喝药轻生。经省内各地和有关部门核实,该信息并不属实。希望广大网友保持理性和冷静,不轻易相信和传播未经证实的信息,共同维护健康有序的网络环境。责任编辑:zx0176

【C++】“多态”特性

文章目录 一、多态的概念二、多态的定义实现1. 多态的构成条件1.1 虚函数1.2 虚函数的重写 2. 多态的调用3. 虚函数重写的其他问题3.1 协变3.2 析构函数的重写 三、override和final关键字四、重载/重写/隐藏的对比五、纯虚函数和抽象类六、多态的原理 C的三大主要特性&#xff…

SmolDocling-256M:极小参数量的视觉语言模型|端到端文档解析方案的另一种思路

背景问题 传统的一站式文档解析工具,包含布局分析、OCR和表格识别等,往往需要结合多个独立的模型,同时根据处理任务的不同调用不同的模型,增加了处理流程的复杂度,并且难以泛化到不同的文档类型。大型视觉语言模型&am…

SUV行驶中被巨石砸下路面,目击者:SUV司机自己爬上来,没受伤!

SUV行驶中被巨石砸下路面。5月28日贵州毕节,SUV行驶中被巨石砸下路面,摩托车司机弃车避险后又赶来查看,目击者:SUV司机自己爬上来,没受伤!SUV行驶中被巨石砸下路面SUV行驶中被巨石砸下路面SUV行驶中被巨石砸下路面SUV行驶中被巨石砸下路面SUV行驶中被巨石砸下路面责任编辑…

一文了解半导体封装测试

1.半导体后端工艺 制作半导体产品的第一步,就是根据所需功能设计芯片(Chip)。然后,再将芯片制作成晶圆(Wafer)。由于晶圆由芯片反复排列而成,当我们细看已完成的晶圆时,可以看到上面…

leetcode hot100刷题日记——28.环形链表2

解答&#xff1a; 方法一&#xff1a;哈希表 class Solution { public:ListNode *detectCycle(ListNode *head) {//哈希表unordered_set<ListNode *>visited;while(head!nullptr){if(visited.count(head)){return head;}visited.insert(head);headhead->next;}return…

NW907NW918美光固态闪存NW920NW930

NW907NW918美光固态闪存NW920NW930 技术解析&#xff1a;美光NW系列固态闪存的核心突破 美光NW907、NW918、NW920、NW930四款固态闪存产品&#xff0c;代表了当前存储技术的顶尖水平。其核心创新在于G9 NAND架构的深度优化&#xff0c;采用更先进的5纳米制程工艺&#xff0c;…

前人栽树,后人乘凉——AdaBoost

一、AdaBoost介绍 AdaBoost的全称是ADAPTIVE BOOSTING&#xff08;自适应增强算法&#xff09;&#xff0c;是一种经典的集成学习算法&#xff0c;它通过组合多个弱学习器来构建一个强学习器。 从表意上看&#xff0c;AdaBoost就是在不断对于错误的知识点进行加深印象&#x…

【深度学习:进阶篇】--2.3.深度学习正则化

学习目标 目标 了解偏差与方差的意义知道L2正则化与L1正则化的数学意义知道Droupout正则化的方法了解早停止法、数据增强法的其它正则化方式 应用 无 目录 学习目标 1 偏差与方差 1.1 数据集划分 1.2 偏差与方差 1.3 解决方法&#xff08;过拟合&#xff09; 2 正则化(…

解决报错error: ‘void_t’ is not a member of ‘std’

解决报错error: ‘void_t’ is not a member of ‘std’ 博主是在编译ceres库时遇到的此报错。 解决方式很简单&#xff0c;将编译使用的c标准设定为c17即可。 例如&#xff0c;在VS2022中&#xff0c;右键单击项目-属性&#xff1a;