├── .DS_Store ├── LeetCode ├── .DS_Store ├── question_11.jpeg ├── #1 Two Sum.md ├── #41 缺失的第一个正数.md ├── #55 跳跃游戏.md ├── #3 最长未重复子字符串.md ├── #50 Pow(x, n).md ├── #53 最大子数组和(Top 100).md ├── #7 反转整数.md ├── #89 格雷码.md ├── #66-加一.md ├── #49 字母异位词分组(Top 100).md ├── #83 移除列表中重复的节点.md ├── #70 爬楼梯(Top 100).md ├── #90 子集 II.md ├── #48 旋转图像(Top 100).md ├── #2 Add Two Numbers.md ├── #9 回文数字.md ├── #58 最后一个单词的长度.md ├── #69 x 的平方根.md ├── #5 求最长的镜像字符串.md ├── #78 子集(Top 100).md ├── #86 分割链表.md ├── #68-文本左右对齐.md ├── #77 组合 .md ├── #75 颜色分类(Top 100).md ├── #27 移除元素.md ├── #32 最长有效括号(Top 100).md ├── #62 不同路径(Top 100).md ├── #46 全排列(Top 100).md ├── #64-最小路径和(Top-100).md ├── #60 排列序列.md ├── #47 全排列 II.md ├── #11 盛最多水的容器.md ├── #59 螺旋矩阵 II.md ├── #24 两两交换链表中的节点.md ├── #88 合并有序数组.md ├── #28 实现 strStr().md ├── #61 旋转链表.md ├── #56 合并区间(Top 100).md ├── #26 删除有序数组中的重复项.md ├── #35 搜索插入位置.md ├── #42 接雨水(Top 100).md ├── #52 N皇后 II.md ├── #29 两数相除.md ├── #40 组合总和 II.md ├── #80 删除有序数组中的重复项 II.md ├── #19 删除链表的倒数第 N 个结点.md ├── #63 不同路径 II.md ├── #22 括号生成(Top 100).md ├── #82 删除排序链表中的重复元素 II.md ├── #39 组合总和(Top 100).md ├── #38 外观数列.md ├── #71 简化路径.md ├── #76 最小覆盖子串(Top 100).md ├── #43 字符串相乘.md ├── #72 编辑距离(Top 100).md ├── #65-有效数字.md ├── #33 搜索旋转排序数组(Top 100).md ├── #14 最长公共前缀.md ├── #6 字符串“之”字形转换 .md ├── #54 螺旋矩阵.md ├── #34 在排序数组中查找元素的第一个和最后一个位置(Top 100).md ├── #73 矩阵置零.md ├── #31 下一个排列 (Top 100).md ├── #81 搜索旋转排序数组 II.md ├── #10 正则表达式匹配.md ├── #21 合并两个有序链表(Top 100).md ├── #74 搜索二维矩阵.md ├── #57 插入区间.md ├── #44 通配符匹配.md ├── #15 三数之和(Top 100).md ├── #16 最接近的三数之和.md ├── #51 N 皇后.md ├── #25 K 个一组翻转链表.md ├── #4 求两个有序数组的中间值.md ├── #79 单词搜索(Top 100).md ├── #20 有效的括号.md ├── #17 电话号码的字母组合.md ├── #23 合并 K 个升序链表(Top 100).md ├── #13 罗马数字转整数.md ├── #12 整数转罗马数字.md └── #18 四数之和 .md ├── README.md ├── LICENSE └── .gitignore /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SwiftCommunityRes/LeetCode--Swift/HEAD/.DS_Store -------------------------------------------------------------------------------- /LeetCode/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SwiftCommunityRes/LeetCode--Swift/HEAD/LeetCode/.DS_Store -------------------------------------------------------------------------------- /LeetCode/question_11.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SwiftCommunityRes/LeetCode--Swift/HEAD/LeetCode/question_11.jpeg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![RSS_icon](https://img.shields.io/badge/RSS-Atom-orange)](https://github.com/SwiftCommunityRes/LeetCode--Swift/releases.atom) 2 | 3 | # [LeetCode--Swift]() 4 | 5 | LeetCode Swift 题解文章会在小专栏首发。本仓库会定期更新 LeetCode Swift 题解。如果希望获取最新文章,欢迎关注小专栏 [LeetCode Swift 解集](https://xiaozhuanlan.com/LeetCode-Swift) 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。 8 | 9 | ## 关于我们 10 | 11 | **Swift社区**是由 Swift 爱好者共同维护的组织,欢迎关注公众号:**Swift社区**,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 12 | 13 | 特别感谢 Swift社区 翻译组的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量。 14 | 15 | ## star & 赞助 16 | 17 | 如果这个库有帮助到您,请 Star 一下。 18 | 19 | **感谢您的赞助:** 我们会将您的赞助用于 Swift社区 的建设与维护。 20 | 21 | ![](https://github.com/SwiftCommunityRes/article-ios/blob/main/Assets/swift-alipay.png?raw=true) ![](https://github.com/SwiftCommunityRes/article-ios/raw/main/Assets/swift-wechat.png) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 SwiftCommunityRes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LeetCode/#1 Two Sum.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区从本期开始会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。 6 | 7 | > 难度水平:简单 8 | 9 | ## 1. 描述 10 | 11 | 已知一个整数数组 `nums` 和一个整数 `target`,取数组中任意两个值相加的和等 整数 `target`,返回这两个值在数组中的索引。 12 | 13 | **假设:** 14 | 15 | 1. 只有一个有效答案 16 | 2. 同一个值不能重复取两次 17 | 3. 可以按任意顺序返回答案 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:nums = [2,7,11,15],target = 9 25 | 输出:[0,1] 26 | 解释:因为 nums[0] + nums[1] == 9,所以返回 [0, 1] 27 | ``` 28 | 29 | **示例 2** 30 | 31 | ``` 32 | 输入:nums = [3,2,4],target = 6 33 | 输出:[1,2] 34 | ``` 35 | 36 | **示例 3** 37 | 38 | ``` 39 | 输入:nums = [3,3],target = 6 40 | 输出: [0,1] 41 | ``` 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class TwoSum { 47 | func twoSum(_ nums: [Int], _ target: Int) -> [Int] { 48 | var dict = [Int: Int]() 49 | 50 | for (i, num) in nums.enumerated() { 51 | if let lastIndex = dict[target - num] { 52 | return [lastIndex, i] 53 | } 54 | 55 | dict[num] = i 56 | } 57 | 58 | fatalError("No valid outputs") 59 | } 60 | } 61 | ``` 62 | 63 | * 主要思想:遍历数组并在字典中存储目标 - nums[i] 64 | * 时间复杂度:O(n) 65 | * 空间复杂度:O(n) 66 | 67 | 点击前往 [LeetCode](https://leetcode.com/problems/two-sum/) 练习 68 | 69 | 该算法题解的 github 仓库地址是:[https://github.com/soapyigu/LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") -------------------------------------------------------------------------------- /LeetCode/#41 缺失的第一个正数.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 40 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | 给你一个未排序的整数数组 `nums` ,请你找出其中没有出现的最小的正整数。 16 | 17 | 请你实现时间复杂度为 `O(n)` 并且只使用常数级别额外空间的解决方案。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:nums = [1,2,0] 25 | 输出:3 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:nums = [3,4,-1,1] 32 | 输出:2 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:nums = [7,8,9,11,12] 39 | 输出:1 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - `1 <= nums.length <= 5 * 10^5` 45 | - -2^31 <= nums[i] <= 2^31 - 1 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class FirstMissingPositive { 51 | func firstMissingPositive(_ nums: [Int]) -> Int { 52 | let set = Set(nums) 53 | 54 | for i in 0.. 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个非负整数数组 `nums` ,你最初位于数组的 **第一个下标** 。 16 | 17 | 数组中的每个元素代表你在该位置可以跳跃的最大长度。 18 | 19 | 判断你是否能够到达最后一个下标。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:nums = [2,3,1,1,4] 27 | 输出:true 28 | 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入:nums = [3,2,1,0,4] 35 | 输出:false 36 | 解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。 37 | ``` 38 | 39 | **约束条件:** 40 | 41 | - `1 <= nums.length <= 3 * 10^4` 42 | - `0 <= nums[i] <= 10^5` 43 | 44 | ## 3. 答案 45 | 46 | ```swift 47 | class JumpGame { 48 | func canJump(_ nums: [Int]) -> Bool { 49 | var maximumIndex = nums[0] 50 | 51 | for (currentIndex, value) in nums.enumerated(){ 52 | 53 | if currentIndex > maximumIndex{ 54 | return false 55 | } 56 | 57 | maximumIndex = max(maximumIndex, currentIndex + value) 58 | } 59 | 60 | return true 61 | } 62 | } 63 | ``` 64 | 65 | * 主要思想:检查每个位置与前一步所能到达的最远距离。如果我走了最后一步,就意味着无法到达。 66 | * 时间复杂度: O(n) 67 | * 空间复杂度: O(1) 68 | 69 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 70 | 71 | 点击前往 [LeetCode](https://leetcode.com/problems/jump-game/ "LeetCode") 练习 72 | 73 | ## 关于我们 74 | 75 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 76 | 77 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 78 | -------------------------------------------------------------------------------- /LeetCode/#3 最长未重复子字符串.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区从本期开始会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。 6 | 7 | > 难度水平:中等 8 | 9 | ## 1. 描述 10 | 11 | 给定一个字符串 `s`, 找出最长未重复的子字符串的长度. 12 | 13 | 14 | ## 2. 示例 15 | 16 | **示例 1** 17 | 18 | ``` 19 | 输入: s = "abcabcbb" 20 | 输出: 3 21 | 解释: 最长为重复的子字符串答案是 "abc", 长度为 3. 22 | ``` 23 | 24 | **示例 2** 25 | 26 | ``` 27 | 输入: s = "bbbbb" 28 | 输出: 1 29 | 解释: 最长为重复的子字符串答案是 "b", 长度为 1. 30 | ``` 31 | 32 | **示例 3** 33 | 34 | ``` 35 | 输入: s = "pwwkew" 36 | 输出: 3 37 | 解释: 最长为重复的子字符串答案是 "wke", 长度为 3. 38 | 注意答案必须是自字符串,“pwke” 是一个子列,而不是一个自字符串. 39 | ``` 40 | 41 | **示例 4** 42 | 43 | ``` 44 | 输入: s = "" 45 | 输出: 0 46 | ``` 47 | ## 3. 答案 48 | 49 | ```swift 50 | class LongestSubstringWithoutRepeatingCharacters { 51 | func lengthOfLongestSubstring(_ s: String) -> Int { 52 | var maxLen = 0, startIdx = 0, charToPos = [Character: Int]() 53 | let sChars = Array(s) 54 | 55 | for (i, char) in sChars.enumerated() { 56 | if let pos = charToPos[char] { 57 | startIdx = max(startIdx, pos) 58 | } 59 | 60 | // update to next valid position 61 | charToPos[char] = i + 1 62 | maxLen = max(maxLen, i - startIdx + 1) 63 | } 64 | 65 | return maxLen 66 | } 67 | } 68 | 69 | ``` 70 | 71 | * 主要思想:使用字典存储非重复子字符串的下一个可能有效字符的位置,然后迭代字符串更新 maxLen、dictionary 和遇到重复时的 startIdx . 72 | * 时间复杂度: O(n) 73 | * 空间复杂度: O(n) 74 | 75 | 点击前往 [LeetCode](https://leetcode.com/problems/longest-substring-without-repeating-characters/) 练习 76 | 77 | 该算法题解的 github 仓库地址是:[https://github.com/soapyigu/LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 78 | -------------------------------------------------------------------------------- /LeetCode/#50 Pow(x, n).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 49 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 实现 `pow(x, n)` ,即计算 `x` 的 `n` 次幂函数(即,`x^n` )。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:x = 2.00000, n = 10 23 | 输出:1024.00000 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入:x = 2.10000, n = 3 30 | 输出:9.26100 31 | ``` 32 | 33 | **示例 3** 34 | 35 | ``` 36 | 输入:x = 2.00000, n = -2 37 | 输出:0.25000 38 | 解释:2-2 = 1/22 = 1/4 = 0.25 39 | ``` 40 | 41 | **约束条件:** 42 | 43 | - `-100.0 < x < 100.0` 44 | - `-2^31 <= n <= 2^31-1` 45 | - `-10^4 <= x^n <= 10^4` 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class Pow { 51 | func myPow(x: Double, _ n: Int) -> Double { 52 | var x = x, n = n 53 | 54 | if n < 0 { 55 | x = 1.0 / x 56 | n = -n 57 | } 58 | 59 | var res = 1.0 60 | 61 | while n > 0 { 62 | if n % 2 != 0 { 63 | res *= x 64 | } 65 | x *= x 66 | n /= 2 67 | } 68 | 69 | return res 70 | } 71 | } 72 | ``` 73 | 74 | * 主要思想:经典递归,先处理正负情况。 75 | * 时间复杂度: O(logn) 76 | * 空间复杂度: O(n) 77 | 78 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 79 | 80 | 点击前往 [LeetCode](https://leetcode.com/problems/powx-n/ "LeetCode") 练习 81 | 82 | ## 关于我们 83 | 84 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 85 | 86 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 87 | -------------------------------------------------------------------------------- /LeetCode/#53 最大子数组和(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 52 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:简单 14 | 15 | ## 1. 描述 16 | 17 | 给你一个整数数组 `nums` ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 18 | 19 | **子数组** 是数组中的一个连续部分。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 27 | 输出:6 28 | 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入:nums = [1] 35 | 输出:1 36 | ``` 37 | 38 | **示例 3** 39 | 40 | ``` 41 | 输入:nums = [5,4,-1,7,8] 42 | 输出:23 43 | ``` 44 | 45 | **约束条件:** 46 | 47 | - `1 <= nums.length <= 10^5` 48 | - `-10^4 <= nums[i] <= 10^4` 49 | 50 | ## 3. 答案 51 | 52 | ```swift 53 | class MaximumSubarray { 54 | func maxSubArray(nums: [Int]) -> Int { 55 | var max_current = nums[0] 56 | var max_global = nums[0] 57 | 58 | for i in 1.. 难度水平:中等 10 | 11 | ## 1. 描述 12 | 给定一个有符号的 32 位整数 x,返回其数字反转的 x。 如果反转 x 导致值超出有符号的 32 位整数范围 `-$2^31$ <= x <= $2^31$ - 1`,则返回 0。 13 | 14 | **假设环境不允许存储 64 位整数(有符号或无符号)。** 15 | 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入: x = 123 23 | 输出: 321 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入: x = -123 30 | 输出: -321 31 | ``` 32 | 33 | **示例 3** 34 | 35 | ``` 36 | 输入: x = 120 37 | 输出: 21 38 | ``` 39 | 40 | **示例 4** 41 | 42 | ``` 43 | 输入: x = 0 44 | 输出: 0 45 | ``` 46 | 47 | 约束条件: 48 | - `-$2^31$ <= x <= $2^31$ - 1` 49 | 50 | ## 3. 答案 51 | 52 | ```swift 53 | class ReverseInteger { 54 | func reverse(_ x: Int) -> Int { 55 | var res = 0 56 | var x = x 57 | while x != 0 { 58 | if res > Int(Int32.max) / 10 || res < Int(Int32.min) / 10 { 59 | return 0 60 | } 61 | res = res * 10 + x % 10 62 | x = x / 10 63 | } 64 | return res 65 | } 66 | } 67 | ``` 68 | 69 | * 主要思想:使用 % 10 反向迭代数字的数字,并使用 * 10 相应地更新结果。 70 | * 注意:适时处理整数溢出。 71 | * 时间复杂度: O(n) 72 | * 空间复杂度: O(1) 73 | 74 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 75 | 76 | 点击前往 [LeetCode](https://leetcode.com/problems/reverse-integer/ "LeetCode") 练习 77 | 78 | ## 关于我们 79 | 80 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 81 | 82 | Swift社区 83 | -------------------------------------------------------------------------------- /LeetCode/#89 格雷码.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 一个 **n 位格雷码序列**是一个 ```2^n``` 整数的序列,其中: 15 | - 每一个序列都包含在 ```[0, 2^-1]``` 的区间中, 16 | - 第一个整数是 `0`, 17 | - 一个整数在序列中出现**不超过一次**, 18 | - 每对相**邻整**数的二进制表示**仅相差一位**, 19 | - 并且,**第一个**和**最后一个**整数的二进制表示**正好相差一位**。 20 | 给定一个整数 `n`, 返回任意有效的 **n 位格雷码序列**。 21 | 22 | ## 2. 示例 23 | 24 | **示例 1** 25 | 26 | ``` 27 | 输入: n = 2 28 | 输出: [0,1,3,2] 29 | 解释: [0,1,3,2] 的二进制表示为 [00,01,11,10]。 30 | - 00 和 01 相差一位 31 | - 01 和 11 相差一位 32 | - 11 和 10 相差一位 33 | - 10 和 00 相差一位 34 | [0,2,3,1] 也同样是有效的格雷码,其二进制表示为 [00,10,11,01]。 35 | - 00 and 10 相差一位 36 | - 10 and 11 相差一位 37 | - 11 and 01 相差一位 38 | - 01 and 00 相差一位 39 | ``` 40 | 41 | **示例 2** 42 | 43 | ``` 44 | 输入: n = 1 45 | 输出: [0,1] 46 | ``` 47 | 48 | 49 | **约束条件** 50 | - `0 <= n <= 16` 51 | 52 | 53 | ## 3. 答案 54 | 55 | ```swift 56 | class GaryCode { 57 | func grayCode(_ n: Int) -> [Int] { 58 | var codes = [0] 59 | for i in 0.. 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给定一个由 **整数** 组成的 **非空** 数组所表示的非负整数,在该数的基础上加一。 16 | 17 | 最高位数字存放在数组的首位, 数组中每个元素只存储**单个**数字。 18 | 19 | 你可以假设除了整数 `0` 之外,这个整数不会以零开头。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:digits = [1,2,3] 27 | 输出:[1,2,4] 28 | 解释:输入数组表示数字 123。 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入:digits = [4,3,2,1] 35 | 输出:[4,3,2,2] 36 | 解释:输入数组表示数字 4321。 37 | ``` 38 | 39 | **示例 3** 40 | 41 | ``` 42 | 输入:digits = [0] 43 | 输出:[1] 44 | ``` 45 | 46 | **约束条件:** 47 | 48 | - `1 <= digits.length <= 100` 49 | - `0 <= digits[i] <= 9` 50 | 51 | ## 3. 答案 52 | 53 | ```swift 54 | class PlusOne { 55 | func plusOne(digits: [Int]) -> [Int] { 56 | var digits = digits 57 | var index = digits.count - 1 58 | 59 | while index >= 0 { 60 | if digits[index] < 9 { 61 | digits[index] += 1 62 | return digits 63 | } 64 | 65 | digits[index] = 0 66 | index -= 1 67 | } 68 | 69 | digits.insert(1, atIndex: 0) 70 | return digits 71 | } 72 | } 73 | ``` 74 | 75 | * 主要思想:迭代并将数组从最后一个更改为第一个。 76 | * 时间复杂度: O(n) 77 | * 空间复杂度: O(1) 78 | 79 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 80 | 81 | 点击前往 [LeetCode](https://leetcode.com/problems/plus-one/ "LeetCode") 练习 82 | 83 | ## 关于我们 84 | 85 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 86 | 87 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 -------------------------------------------------------------------------------- /LeetCode/#49 字母异位词分组(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 48 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给你一个字符串数组,请你将 **字母异位词** 组合在一起。可以按任意顺序返回结果列表。 18 | 19 | **字母异位词** 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"] 27 | 输出: [["bat"],["nat","tan"],["ate","eat","tea"]] 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入: strs = [""] 34 | 输出: [[""]] 35 | ``` 36 | 37 | **示例 3** 38 | 39 | ``` 40 | 输入: strs = ["a"] 41 | 输出: [["a"]] 42 | ``` 43 | 44 | **约束条件:** 45 | 46 | - `1 <= strs.length <= 10^4` 47 | - `0 <= strs[i].length <= 100` 48 | - `strs[i]` 仅包含小写字母 49 | 50 | ## 3. 答案 51 | 52 | ```swift 53 | class GroupAnagrams { 54 | func groupAnagrams(_ strs: [String]) -> [[String]] { 55 | var sortedStrToStrs = [String: [String]]() 56 | 57 | for str in strs { 58 | let sortedStr = String(str.sorted()) 59 | 60 | sortedStrToStrs[sortedStr, default: []].append(str) 61 | } 62 | 63 | return Array(sortedStrToStrs.values) 64 | } 65 | } 66 | ``` 67 | 68 | * 主要思想:对字符串数组进行迭代,并使用相同的排序字符串对字符串进行分类。 69 | * 时间复杂度: O(nmlogm), n表示单词个数,m表示单词长度 70 | * 空间复杂度: O(n) 71 | 72 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 73 | 74 | 点击前往 [LeetCode](https://leetcode.com/problems/group-anagrams/ "LeetCode") 练习 75 | 76 | ## 关于我们 77 | 78 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 79 | 80 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 81 | -------------------------------------------------------------------------------- /LeetCode/#83 移除列表中重复的节点.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 给定一个排序链表的 `head` 指针,*删除所有重复的节点,从而每一个元素仅显示一次*。同时,*返回**排序**链表*。 15 | 16 | ## 2. 示例 17 | 18 | **示例 1** 19 | 20 | ![](https://assets.leetcode.com/uploads/2021/01/04/list1.jpg) 21 | 22 | ``` 23 | 输入: head = [1,1,2] 24 | 输出: [1,2] 25 | ``` 26 | 27 | **示例 2** 28 | ![](https://assets.leetcode.com/uploads/2021/01/04/list2.jpg) 29 | 30 | ``` 31 | 输入: head = [1,1,2,3,3] 32 | 输出: [1,2,3] 33 | ``` 34 | 35 | **约束条件** 36 | 37 | - 链表中节点的数目在 `[0, 300]` 范围之间。 38 | - `-100 <= Node.val <= 100` 39 | - 该链表保证为递增顺序的排序链表。 40 | 41 | 42 | ## 3. 答案 43 | 44 | ```swift 45 | class RemoveDuplicatesFromSortedList { 46 | func deleteDuplicates(_ head: ListNode?) -> ListNode? { 47 | guard let head = head else { 48 | return nil 49 | } 50 | 51 | var curt = head 52 | 53 | while curt.next != nil { 54 | if curt.next!.val == curt.val { 55 | curt.next = curt.next!.next 56 | } else { 57 | curt = curt.next! 58 | } 59 | } 60 | 61 | return head 62 | } 63 | } 64 | ``` 65 | 66 | * 主要思想:迭代列表,通过将 `next` 替换为 `next.next` 来跳过重复项。 67 | * 时间复杂度: O(n) 68 | * 空间复杂度: O(1) 69 | 70 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 71 | 72 | 点击前往 [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list/ "LeetCode") 练习 73 | 74 | ## 关于我们 75 | 76 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 77 | 78 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 79 | -------------------------------------------------------------------------------- /LeetCode/#70 爬楼梯(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 69 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:简单 14 | 15 | ## 1. 描述 16 | 17 | 假设你正在爬楼梯。需要 `n` 阶你才能到达楼顶。 18 | 19 | 每次你可以爬 `1` 或 `2` 个台阶。你有多少种不同的方法可以爬到楼顶呢? 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:n = 2 27 | 输出:2 28 | 解释:有两种方法可以爬到楼顶。 29 | 1. 1 阶 + 1 阶 30 | 2. 2 阶 31 | ``` 32 | 33 | **示例 2** 34 | 35 | ``` 36 | 输入:n = 3 37 | 输出:3 38 | 解释:有三种方法可以爬到楼顶。 39 | 1. 1 阶 + 1 阶 + 1 阶 40 | 2. 1 阶 + 2 阶 41 | 3. 2 阶 + 1 阶 42 | ``` 43 | 44 | **约束条件:** 45 | 46 | - `1 <= n <= 45` 47 | 48 | ## 3. 答案 49 | 50 | ```swift 51 | class ClimbingStairs { 52 | func climbStairs(_ n: Int) -> Int { 53 | if n < 0 { 54 | return 0 55 | } 56 | if n == 0 || n == 1 { 57 | return 1 58 | } 59 | 60 | var prev = 0, post = 1, total = 0 61 | 62 | for i in 1...n { 63 | total = prev + post 64 | 65 | prev = post 66 | post = total 67 | } 68 | 69 | return total 70 | } 71 | } 72 | ``` 73 | 74 | * 主要思想:动态编程,`dp = dp + dp[i - 2]`。 75 | * 时间复杂度: O(n) 76 | * 空间复杂度: O(1) 77 | 78 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 79 | 80 | 点击前往 [LeetCode](https://leetcode.com/problems/climbing-stairs/ "LeetCode") 练习 81 | 82 | ## 关于我们 83 | 84 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 85 | 86 | Swift社区 87 | -------------------------------------------------------------------------------- /LeetCode/#90 子集 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 给定一个整数数组 `nums`,该数组可能包含重复的元素,返回所有可能的子集(幂集)。 15 | 16 | 题解的集合**必须不能**包涵重复的子集。返回任意顺序的题解。 17 | 18 | ## 2. 示例 19 | 20 | **示例 1** 21 | 22 | ``` 23 | 输入: nums = [1,2,2] 24 | 输出: [[],[1],[1,2],[1,2,2],[2],[2,2]] 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入: nums = [0] 31 | 输出: [[],[0]] 32 | ``` 33 | 34 | **约束条件** 35 | - `1 <= nums.length <= 10` 36 | - `-10 <= nums[i]] <= 10` 37 | 38 | ## 3. 答案 39 | 40 | ```swift 41 | class SubsetsII { 42 | func subsetsWithDup(nums: [Int]) -> [[Int]] { 43 | var res = [[Int]](), path = [Int]() 44 | 45 | let nums = nums.sorted(by: <) 46 | 47 | _dfs(&res, &path, nums, 0) 48 | 49 | return res 50 | } 51 | 52 | private func _dfs(inout res: [[Int]], inout _ path:[Int], _ nums: [Int], _ index: Int) { 53 | res.append(path) 54 | 55 | for i in index.. 0 && nums[i] == nums[i - 1] && i != index { 57 | continue 58 | } 59 | 60 | path.append(nums[i]) 61 | _dfs(&res, &path, nums, i + 1) 62 | path.removeLast() 63 | } 64 | } 65 | } 66 | Footer 67 | 68 | 69 | ``` 70 | 71 | * 主要思想:经典深度优先搜索,采用第一次出现避免重复 72 | * 时间复杂度: O(n^n) 73 | * 空间复杂度: O(n) 74 | 75 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 76 | 77 | 点击前往 [LeetCode](https://leetcode.com/problems/subsets-ii/ "LeetCode") 练习 78 | 79 | ## 关于我们 80 | 81 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 82 | 83 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 84 | -------------------------------------------------------------------------------- /LeetCode/#48 旋转图像(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 47 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给定一个 `n × n` 的二维矩阵 `matrix` 表示一个图像。请你将图像顺时针旋转 `90` 度。 18 | 19 | 你必须在 **原地** 旋转图像,这意味着你需要直接修改输入的二维矩阵。**请不要** 使用另一个矩阵来旋转图像。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 27 | 输出:[[7,4,1],[8,5,2],[9,6,3]] 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 34 | 输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]] 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `n == matrix.length == matrix[i].length` 40 | - `1 <= n <= 20` 41 | - `-1000 <= matrix[i][j] <= 1000` 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class RotateImage { 47 | func rotate(_ matrix: inout [[Int]]) { 48 | let n = matrix.count 49 | 50 | for layer in 0.. 难度水平:中等 8 | 9 | ## 描述 10 | 11 | 已知两个非负整数(`例如:l1 = 342,l2 = 465`),将数字分别按相反的顺序存储到链表中(`例如:l1 = [2,4,3],l2 = [5,6,4]`),每个节点都包含一个数字,将两个数字相加并将总和作为链表返回(`例如:[7,0,8]`)。 12 | 13 | 假设这两个数字不包含任何前导零(`例如:`~~012~~),除了数字 0 本身。 14 | 15 | ## 示例 16 | 17 | **示例 1** 18 | 19 | ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7e825f8225274c4888fb02183f163807~tplv-k3u1fbpfcp-zoom-1.image) 20 | 21 | ``` 22 | 输入:l1 = [2,4,3],l2 = [5,6,4] 23 | 产出:[7,0,8] 24 | 说明:342 + 465 = 807 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入:l1 = [0],l2 = [0] 31 | 产出:[0] 32 | ``` 33 | 34 | **示例 3** 35 | 36 | ``` 37 | 输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 38 | 产出:[8,9,9,9,0,0,0,1] 39 | ``` 40 | 41 | **限制** 42 | 43 | * 每个链表中的节点数在 [1, 100] 范围内 44 | * 0 <= 节点值 <= 9 45 | * 保证列表中没有前导零的数字 46 | 47 | ## 答案 48 | 49 | ```swift 50 | /** 51 | * Definition for singly-linked list. 52 | * public class ListNode { 53 | * public var val: Int 54 | * public var next: ListNode? 55 | * public init(_ val: Int) { 56 | * self.val = val 57 | * self.next = nil 58 | * } 59 | * } 60 | */ 61 | class AddTwoNumbers { 62 | func addTwoNumbers(l1: ListNode?, _ l2: ListNode?) -> ListNode? { 63 | guard let l1 = l1 else {return l2} 64 | guard let l2 = l2 else {return l1} 65 | 66 | let outputNode = ListNode((l1.val + l2.val)%10) 67 | if l1.val + l2.val > 9 { 68 | outputNode.next = addTwoNumbers(addTwoNumbers(l1.next, l2.next), 69 | ListNode(1)) 70 | } else { 71 | outputNode.next = addTwoNumbers(l1.next, l2.next) 72 | } 73 | return outputNode 74 | } 75 | } 76 | ``` 77 | 78 | * 主要思想:使用进位并遍历两个链表 79 | * 时间复杂度:O(n) 80 | * 空间复杂度:O(1) 81 | 82 | 点击前往 [LeetCode](https://leetcode.com/problems/add-two-numbers/) 练习 83 | 84 | 该算法题解的 github 仓库地址是:[https://github.com/soapyigu/LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") -------------------------------------------------------------------------------- /LeetCode/#9 回文数字.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:简单 10 | 11 | ## 1. 描述 12 | 给定一个整数 `x`,如果 `x` 是回文整数,则返回 `true`。 13 | 14 | 当一个整数向后读与向前读相同时,它就是**回文**。例如,`121` 是回文,而 `123` 不是。 15 | 16 | 17 | 18 | ## 2. 示例 19 | 20 | **示例 1** 21 | 22 | ``` 23 | 输入: x = 121 24 | 输出: 真 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入: x = -121 31 | 输出: 假 32 | 说明: 从左到右依次为 -121。 从右到左,它变成 121-。 因此它不是回文。 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入: x = 10 39 | 输出: 假 40 | 说明: 从右到左读取 01。 因此它不是回文。 41 | ``` 42 | 43 | **示例 4** 44 | 45 | ``` 46 | 输入: x = -101 47 | 输出: 假 48 | ``` 49 | 50 | **约束条件:** 51 | - `-$2^31$ <= x <= $2^31$ - 1` 52 | 53 | **跟进:**你能在不将整数转换为字符串的情况下解决它吗? 54 | 55 | ## 3. 答案 56 | 57 | ```swift 58 | class PalindromeNumber { 59 | func isPalindrome(x: Int) -> Bool { 60 | guard x >= 0 else { 61 | return false 62 | } 63 | var x = x 64 | var div = 1 65 | while (x / div >= 10) { 66 | div = div * 10 67 | } 68 | while (x > 0) { 69 | var left = x / div 70 | var right = x % 10 71 | if (left != right) { 72 | return false 73 | } 74 | x = (x % div) / 10 75 | div = div / 100 76 | } 77 | return true 78 | } 79 | } 80 | ``` 81 | 82 | * 主要思想:负数不是回文。 83 | * 时间复杂度: O(1) 84 | * 空间复杂度: O(1) 85 | 86 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 87 | 88 | 点击前往 [LeetCode](https://leetcode.com/problems/palindrome-number/ "LeetCode") 练习 89 | 90 | ## 关于我们 91 | 92 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 93 | 94 | Swift社区 95 | -------------------------------------------------------------------------------- /LeetCode/#58 最后一个单词的长度.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 56 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:简单 10 | 11 | ## 1. 描述 12 | 13 | 给你一个字符串 `s`,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 **最后一个** 单词的长度。 14 | 15 | 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:s = "Hello World" 23 | 输出:5 24 | 解释:最后一个单词是“World”,长度为5。 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入:s = " fly me to the moon " 31 | 输出:4 32 | 解释:最后一个单词是“moon”,长度为4。 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:s = "luffy is still joyboy" 39 | 输出:6 40 | 解释:最后一个单词是长度为6的“joyboy”。 41 | ``` 42 | 43 | **约束条件:** 44 | 45 | - `1 <= s.length <= 10^4` 46 | - `s` 仅有英文字母和空格 `' '` 组成 47 | - `s` 中至少存在一个单词 48 | 49 | ## 3. 答案 50 | 51 | ```swift 52 | class LengthLastWord { 53 | func lengthOfLastWord(s: String) -> Int { 54 | var res = 0 55 | var sChars = [Character](s.characters) 56 | 57 | guard sChars.count != 0 else { 58 | return 0 59 | } 60 | 61 | for i in (0...sChars.count - 1).reverse() { 62 | if res == 0 { 63 | if sChars[i] == " " { 64 | continue 65 | } else { 66 | res += 1 67 | } 68 | } else { 69 | if sChars[i] == " " { 70 | break 71 | } else { 72 | res += 1 73 | } 74 | } 75 | } 76 | 77 | return res 78 | } 79 | } 80 | ``` 81 | 82 | * 主要思想:向后迭代字符串。 83 | * 时间复杂度: O(n) 84 | * 空间复杂度: O(n) 85 | 86 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 87 | 88 | 点击前往 [LeetCode](https://leetcode.com/problems/length-of-last-word/ "LeetCode") 练习 89 | 90 | ## 关于我们 91 | 92 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 93 | 94 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 95 | -------------------------------------------------------------------------------- /LeetCode/#69 x 的平方根.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 68 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给你一个非负整数 `x` ,计算并返回 `x` 的 **算术平方根** 。 16 | 17 | 由于返回类型是整数,结果只保留 **整数部分** ,小数部分将被 **舍去** 。 18 | 19 | **注意:** 不允许使用任何内置指数函数和算符,例如 `pow(x, 0.5)` 或者 `x ** 0.5` 。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:x = 4 27 | 输出:2 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:x = 8 34 | 输出:2 35 | 解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。 36 | ``` 37 | 38 | **约束条件:** 39 | 40 | - `0 <= x <= 2^31 - 1` 41 | 42 | ## 3. 答案 43 | 44 | ```swift 45 | class Sqrtx { 46 | func mySqrt(_ x: Int) -> Int { 47 | guard x >= 0 else { 48 | return 0 49 | } 50 | 51 | var left = 0, right = x / 2 + 1 52 | 53 | while left <= right { 54 | let mid = (right - left) / 2 + left 55 | 56 | if mid * mid == x { 57 | return mid 58 | } else if mid * mid < x { 59 | left = mid + 1 60 | } else { 61 | right = mid - 1 62 | } 63 | } 64 | 65 | return right 66 | } 67 | } 68 | ``` 69 | 70 | * 主要思想:二分查找,应该从 `x / 2 + 1` 开始,所以它的平方是 `x + x ^ 2 / 4 + 1`,它肯定大于 `x`。 71 | * 时间复杂度: O(logn) 72 | * 空间复杂度: O(1) 73 | 74 | > **注意:** 请使用(右-左)/ 2 +左来获得中间以防整数溢出 75 | 76 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 77 | 78 | 点击前往 [LeetCode](https://leetcode.com/problems/sqrtx/ "LeetCode") 练习 79 | 80 | ## 关于我们 81 | 82 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 83 | 84 | Swift社区 85 | -------------------------------------------------------------------------------- /LeetCode/#5 求最长的镜像字符串.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给定一个字符串 `s`, 返回 `s` 中的最长回文子字符串. 14 | 15 | 16 | ## 2. 示例 17 | 18 | **示例 1** 19 | 20 | ``` 21 | 输入: s = "babad" 22 | 输出: "bab" 23 | 解释: "aba" 同样是有效答案。 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入: s = "cbbd" 30 | 输出: "bb" 31 | ``` 32 | 33 | **示例 3** 34 | 35 | ``` 36 | 输入: s = "a" 37 | 输出: "a" 38 | ``` 39 | 40 | **示例 4** 41 | 42 | ``` 43 | 输入: s = "ac" 44 | 输出: "a" 45 | ``` 46 | 47 | 约束条件: 48 | - `1 <= s.length <= 1000` 49 | - `s` 仅由数字和英文字母组成。 50 | 51 | ## 3. 答案 52 | 53 | ```swift 54 | class LongestPalindromicSubstring { 55 | func longestPalindrome(_ s: String) -> String { 56 | guard s.count > 1 else { 57 | return s 58 | } 59 | 60 | let sChars = Array(s) 61 | var maxLen = 0, start = 0 62 | 63 | for i in 0..= 0 && r < chars.count && chars[l] == chars[r] { 75 | l -= 1 76 | r += 1 77 | } 78 | 79 | if maxLen < r - l - 1 { 80 | start = l + 1 81 | maxLen = r - l - 1 82 | } 83 | } 84 | } 85 | ``` 86 | 87 | * 主要思想:从中心的每个索引中找到最长的回文字符串。 88 | * 时间复杂度: O(n^2) 89 | * 空间复杂度: O(1) 90 | 91 | 点击前往 [LeetCode](https://leetcode.com/problems/longest-palindromic-substring/) 练习 92 | 93 | 该算法题解的 github 仓库地址是:[https://github.com/soapyigu/LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 94 | -------------------------------------------------------------------------------- /LeetCode/#78 子集(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 77 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给你一个整数数组 `nums` ,数组中的元素 **互不相同** 。返回该数组所有可能的子集(幂集)。 18 | 19 | 解集 **不能** 包含重复的子集。你可以按 **任意顺序** 返回解集。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:nums = [1,2,3] 27 | 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:nums = [0] 34 | 输出:[[],[0]] 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `1 <= nums.length <= 10` 40 | - `-10 <= nums[i] <= 10` 41 | - `nums` 中的所有元素 **互不相同** 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class Subsets { 47 | func subsets(nums: [Int]) -> [[Int]] { 48 | var res = [[Int]]() 49 | var path = [Int]() 50 | 51 | let nums = nums.sorted(by: <) 52 | 53 | _dfs(&res, &path, nums, 0) 54 | 55 | return res 56 | } 57 | 58 | private func _dfs(inout res: [[Int]], inout _ path: [Int], _ nums: [Int], _ index: Int) { 59 | // termination case 60 | res.append(path) 61 | 62 | for i in index.. 84 | -------------------------------------------------------------------------------- /LeetCode/#86 分割链表.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 给定一个链表的 `head` 指针以及一个数值 `x`,分割此链表,使所有小于 `x` 值的节点排在那些大于或等于 `x` 值的节点前面。 15 | 16 | 你需要确保那些在两个分隔部分链表的节点保持原有的相对顺序。 17 | 18 | ## 2. 示例 19 | 20 | **示例 1** 21 | 22 | ![](https://assets.leetcode.com/uploads/2021/01/04/partition.jpg) 23 | 24 | ``` 25 | 输入: head = [1,4,3,2,5,2], x = 3 26 | 输出: [1,2,2,4,3,5] 27 | ``` 28 | 29 | **示例 2** 30 | 31 | ``` 32 | 输入: head = [2,1], x = 2 33 | 输出: [1,2] 34 | ``` 35 | 36 | **约束条件** 37 | 38 | - 链表中节点的数目在 `[0, 200]` 范围之间。 39 | - `-100 <= Node.val <= 100` 40 | - `-200 <= x <= 200` 41 | 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class PartitionList { 47 | func partition(_ head: ListNode?, _ x: Int) -> ListNode? { 48 | let prevDummy = ListNode(0), postDummy = ListNode(0) 49 | var prev = prevDummy, post = postDummy 50 | 51 | var node = head 52 | 53 | while node != nil { 54 | let next = node!.next 55 | node!.next = nil 56 | 57 | if node!.val < x { 58 | prev.next = node 59 | prev = prev.next! 60 | } else { 61 | post.next = node 62 | post = post.next! 63 | } 64 | node = next 65 | } 66 | 67 | prev.next = postDummy.next 68 | 69 | return prevDummy.next 70 | } 71 | } 72 | ``` 73 | 74 | * 主要思想:尾部插入并合并两个链表,使用 dummy 以避免边缘情况。 75 | * 时间复杂度: O(n) 76 | * 空间复杂度: O(1) 77 | 78 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 79 | 80 | 点击前往 [LeetCode](https://leetcode.com/problems/partition-list/ "LeetCode") 练习 81 | 82 | ## 关于我们 83 | 84 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 85 | 86 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 87 | -------------------------------------------------------------------------------- /LeetCode/#68-文本左右对齐.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 66 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给你两个二进制字符串,返回它们的和(用二进制表示)。 16 | 17 | 输入为 **非空** 字符串且只包含数字 `1` 和 `0`。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入: a = "11", b = "1" 25 | 输出: "100" 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入: a = "1010", b = "1011" 32 | 输出: "10101" 33 | ``` 34 | 35 | **约束条件:** 36 | 37 | - 每个字符串仅由字符 `'0'` 或 `'1'` 组成。` 38 | - `1 <= a.length, b.length <= 10^4` 39 | - 字符串如果不是 `"0"` ,就都不含前导零。 40 | 41 | ## 3. 答案 42 | 43 | ```swift 44 | class AddBinary { 45 | func addBinary(_ a: String, _ b: String) -> String { 46 | let a = Array(a), b = Array(b) 47 | var res = "", carry = 0, i = a.count - 1, j = b.count - 1 48 | 49 | while i >= 0 || j >= 0 || carry > 0 { 50 | var sum = carry 51 | 52 | if i >= 0 { 53 | sum += Int(String(a[i]))! 54 | i -= 1 55 | } 56 | if j >= 0 { 57 | sum += Int(String(b[j]))! 58 | j -= 1 59 | } 60 | 61 | res = "\(sum % 2)" + res 62 | carry = sum / 2 63 | } 64 | 65 | return res 66 | } 67 | } 68 | ``` 69 | 70 | * 主要思想:使用进位和从最后到开始迭代。 71 | * 时间复杂度: O(n) 72 | * 空间复杂度: O(n) 73 | 74 | > **注意:** Swift没有办法访问O(1)字符串中的字符,因此我们必须首先将字符串转换为字符数组 75 | 76 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 77 | 78 | 点击前往 [LeetCode](https://leetcode.com/problems/add-binary/ "LeetCode") 练习 79 | 80 | ## 关于我们 81 | 82 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 83 | 84 | Swift社区 85 | -------------------------------------------------------------------------------- /LeetCode/#77 组合 .md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 76 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定两个整数 `n` 和 `k`,返回范围 `[1, n]` 中所有可能的 `k` 个数的组合。 16 | 17 | 你可以按 **任何顺序** 返回答案。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:n = 4, k = 2 25 | 输出: 26 | [ 27 | [2,4], 28 | [3,4], 29 | [2,3], 30 | [1,2], 31 | [1,3], 32 | [1,4], 33 | ] 34 | ``` 35 | 36 | **示例 2** 37 | 38 | ``` 39 | 输入:n = 1, k = 1 40 | 输出:[[1]] 41 | ``` 42 | 43 | **约束条件:** 44 | 45 | - `1 <= n <= 20` 46 | - `1 <= k <= n` 47 | 48 | ## 3. 答案 49 | 50 | ```swift 51 | class Combinations { 52 | func combine(n: Int, _ k: Int) -> [[Int]] { 53 | var res = [[Int]]() 54 | var path = [Int]() 55 | let nums = [Int](1...n) 56 | 57 | _dfs(nums, &res, &path, 0, k) 58 | 59 | return res 60 | } 61 | 62 | private func _dfs(nums: [Int], inout _ res: [[Int]], inout _ path: [Int], _ index: Int, _ k: Int) { 63 | if path.count == k { 64 | res.append([Int](path)) 65 | return 66 | } 67 | 68 | for i in index.. 90 | -------------------------------------------------------------------------------- /LeetCode/#75 颜色分类(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 74 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给定一个包含红色、白色和蓝色、共 `n` 个元素的数组 `nums` ,**原地**对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 18 | 19 | 我们使用整数 `0`、 `1` 和 `2` 分别表示红色、白色和蓝色。 20 | 21 | 必须在不使用库的 sort 函数的情况下解决这个问题。 22 | 23 | ## 2. 示例 24 | 25 | **示例 1** 26 | 27 | ``` 28 | 输入:nums = [2,0,2,1,1,0] 29 | 输出:[0,0,1,1,2,2] 30 | ``` 31 | 32 | **示例 2** 33 | 34 | ``` 35 | 输入:nums = [2,0,1] 36 | 输出:[0,1,2] 37 | ``` 38 | 39 | **约束条件:** 40 | 41 | - `n == nums.length` 42 | - `1 <= n <= 300` 43 | - `nums[i]` 为 `0`、`1` 或 `2` 44 | 45 | ## 3. 答案 46 | 47 | ```swift 48 | class SortColors { 49 | func sortColors(_ nums: inout [Int]) { 50 | var red = 0, blue = nums.count - 1, i = 0 51 | 52 | while i <= blue { 53 | if nums[i] == 0 { 54 | _swap(&nums, i, red) 55 | red += 1 56 | i += 1 57 | } else if nums[i] == 1 { 58 | i += 1 59 | } else { 60 | _swap(&nums, i, blue) 61 | blue -= 1 62 | } 63 | } 64 | } 65 | 66 | fileprivate func _swap(_ nums: inout [T], _ p: Int, _ q: Int) { 67 | (nums[p], nums[q]) = (nums[q], nums[p]) 68 | } 69 | } 70 | ``` 71 | 72 | * 主要思想:桶排序。 73 | * 时间复杂度: O(n) 74 | * 空间复杂度: O(1) 75 | 76 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 77 | 78 | 点击前往 [LeetCode](https://leetcode.com/problems/sort-colors/ "LeetCode") 练习 79 | 80 | ## 关于我们 81 | 82 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 83 | 84 | Swift社区 85 | -------------------------------------------------------------------------------- /LeetCode/#27 移除元素.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 26 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给你一个数组 `nums` 和一个值 `val`,你需要 `原地` 移除所有数值等于 `val` 的元素,并返回移除后数组的新长度。 16 | 17 | 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 `原地` **修改输入数组**。 18 | 19 | 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 20 | 21 | **说明:** 22 | 23 | 为什么返回数值是整数,但输出的答案是数组呢? 24 | 25 | 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 26 | 27 | 你可以想象内部操作如下: 28 | 29 | ```c 30 | // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 31 | int len = removeElement(nums, val); 32 | 33 | // 在函数里修改输入数组对于调用者是可见的。 34 | // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 35 | for (int i = 0; i < len; i++) { 36 | print(nums[i]); 37 | } 38 | ``` 39 | 40 | ## 2. 示例 41 | 42 | **示例 1** 43 | 44 | ``` 45 | 输入:nums = [3,2,2,3], val = 3 46 | 输出:2, nums = [2,2] 47 | 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。 48 | ``` 49 | 50 | **示例 2** 51 | 52 | ``` 53 | 输入:nums = [0,1,2,2,3,0,4,2], val = 2 54 | 输出:5, nums = [0,1,4,0,3] 55 | 解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。 56 | ``` 57 | 58 | **约束条件:** 59 | 60 | - `0 <= nums.length <= 100` 61 | - `0 <= nums[i] <= 50` 62 | - `0 <= val <= 100` 63 | 64 | ## 3. 答案 65 | 66 | ```swift 67 | class RemoveElement { 68 | func removeElement(inout nums: [Int], _ val: Int) -> Int { 69 | nums = nums.filter { (num) in num != val } 70 | return nums.count 71 | } 72 | } 73 | ``` 74 | 75 | * 主要思想:保留一个索引,向前移动时将该索引处的元素与 val 进行比较 76 | * 时间复杂度: O(n) 77 | * 空间复杂度: O(1) 78 | 79 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 80 | 81 | 点击前往 [LeetCode](https://leetcode.com/problems/remove-element/ "LeetCode") 练习 82 | 83 | ## 关于我们 84 | 85 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 86 | 87 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 88 | -------------------------------------------------------------------------------- /LeetCode/#32 最长有效括号(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 31 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:困难 14 | 15 | ## 1. 描述 16 | 17 | 给你一个只包含 `'('` 和 `')'` 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:s = "(()" 25 | 输出:2 26 | 解释:最长有效括号子串是 "()" 27 | ``` 28 | 29 | **示例 2** 30 | 31 | ``` 32 | 输入:s = ")()())" 33 | 输出:4 34 | 解释:最长有效括号子串是 "()()" 35 | ``` 36 | 37 | **示例 3** 38 | 39 | ``` 40 | 输入:s = "" 41 | 输出:0 42 | ``` 43 | 44 | **约束条件:** 45 | 46 | - `0 <= s.length <= 3 * 10^4` 47 | - `s[i]` 为 `'('` 或 `')'` 48 | 49 | ## 3. 答案 50 | 51 | ```swift 52 | class LongestValidParentheses { 53 | func longestValidParentheses(_ s: String) -> Int { 54 | var stack = [Int](), longest = 0, start = 0 55 | 56 | for (i, char) in s.enumerated() { 57 | if char == "(" { 58 | stack.append(i) 59 | } else { 60 | if !stack.isEmpty { 61 | stack.removeLast() 62 | 63 | if let last = stack.last { 64 | longest = max(longest, i - last) 65 | } else { 66 | longest = max(longest, i - start + 1) 67 | } 68 | } else { 69 | start = i + 1 70 | } 71 | } 72 | } 73 | 74 | return longest 75 | } 76 | } 77 | ``` 78 | 79 | * 主要思想:将索引推到堆栈中,遇到 “)”。 80 | * 时间复杂度: O(n) 81 | * 空间复杂度: O(n) 82 | 83 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 84 | 85 | 点击前往 [LeetCode](https://leetcode.com/problems/longest-valid-parentheses/ "LeetCode") 练习 86 | 87 | ## 关于我们 88 | 89 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 90 | 91 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 92 | -------------------------------------------------------------------------------- /LeetCode/#62 不同路径(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 62 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 一个机器人位于一个 `m x n` 网格的左上角 (起始点在下图中标记为 “Start” )。 16 | 17 | 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 18 | 19 | 问总共有多少条不同的路径? 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:m = 3, n = 7 27 | 输出:28 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:m = 3, n = 2 34 | 输出:3 35 | 解释: 36 | 从左上角开始,总共有 3 条路径可以到达右下角。 37 | 1. 向右 -> 向下 -> 向下 38 | 2. 向下 -> 向下 -> 向右 39 | 3. 向下 -> 向右 -> 向下 40 | ``` 41 | 42 | **示例 3** 43 | 44 | ``` 45 | 输入:m = 7, n = 3 46 | 输出:28 47 | ``` 48 | 49 | **示例 4** 50 | 51 | ``` 52 | 输入:m = 3, n = 3 53 | 输出:6 54 | ``` 55 | 56 | **约束条件:** 57 | 58 | - `1 <= m, n <= 100` 59 | - 题目数据保证答案小于等于 `2 * 10^9` 60 | 61 | ## 3. 答案 62 | 63 | ```swift 64 | class UniquePaths { 65 | func uniquePaths(m: Int, _ n: Int) -> Int { 66 | var pathNums = Array(count: m, repeatedValue: Array(count: n, repeatedValue: 0)) 67 | return _helper(&pathNums, m - 1, n - 1) 68 | } 69 | 70 | private func _helper(inout pathNums: [[Int]], _ m: Int, _ n: Int) -> Int { 71 | if m < 0 || n < 0 { 72 | return 0 73 | } 74 | if m == 0 || n == 0 { 75 | return 1 76 | } 77 | 78 | if pathNums[m][n] != 0 { 79 | return pathNums[m][n] 80 | } 81 | pathNums[m][n] = _helper(&pathNums, m - 1, n) + _helper(&pathNums, m, n - 1) 82 | 83 | return pathNums[m][n] 84 | } 85 | } 86 | ``` 87 | 88 | * 主要思想:2D动态编程,使用2D数组作为缓存来存储计算数据。 89 | * 时间复杂度: O(mn) 90 | * 空间复杂度: O(mn) 91 | 92 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 93 | 94 | 点击前往 [LeetCode](https://leetcode.com/problems/unique-paths/ "LeetCode") 练习 95 | 96 | ## 关于我们 97 | 98 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 99 | 100 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 101 | -------------------------------------------------------------------------------- /LeetCode/#46 全排列(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 44 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给定一个不含重复数字的数组 `nums` ,返回其 所有可能的全排列 。你可以 **按任意顺序** 返回答案。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:nums = [1,2,3] 25 | 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:nums = [0,1] 32 | 输出:[[0,1],[1,0]] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:nums = [1] 39 | 输出:[[1]] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - `1 <= nums.length <= 6` 45 | - `-10 <= nums[i] <= 10` 46 | - `nums` 中的所有整数 **互不相同** 47 | 48 | ## 3. 答案 49 | 50 | ```swift 51 | class Permutations { 52 | func permute(_ nums: [Int]) -> [[Int]] { 53 | var res = [[Int]]() 54 | var path = [Int]() 55 | var isVisited = [Bool](repeating: false, count: nums.count) 56 | 57 | dfs(&res, &path, &isVisited, nums) 58 | 59 | return res 60 | } 61 | 62 | private func dfs(_ res: inout [[Int]], _ path: inout [Int], _ isVisited: inout [Bool], _ nums: [Int]) { 63 | guard path.count != nums.count else { 64 | res.append(path) 65 | return 66 | } 67 | 68 | for (i, num) in nums.enumerated() where !isVisited[i] { 69 | path.append(num) 70 | isVisited[i] = true 71 | dfs(&res, &path, &isVisited, nums) 72 | isVisited[i] = false 73 | path.removeLast() 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | * 主要思想:经典的深度优先搜索,记住回溯。 80 | * 时间复杂度: O(n^n) 81 | * 空间复杂度: O(n) 82 | 83 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 84 | 85 | 点击前往 [LeetCode](https://leetcode.com/problems/permutations/ "LeetCode") 练习 86 | 87 | ## 关于我们 88 | 89 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 90 | 91 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 92 | -------------------------------------------------------------------------------- /LeetCode/#64-最小路径和(Top-100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 63 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | 16 | ## 1. 描述 17 | 18 | 给定一个包含非负整数的 `m x n` 网格 `grid` ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 19 | 20 | **说明:** 每次只能向下或者向右移动一步。 21 | 22 | ## 2. 示例 23 | 24 | **示例 1** 25 | 26 | ``` 27 | 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 28 | 输出:7 29 | 解释:因为路径 1→3→1→1→1 的总和最小。 30 | ``` 31 | 32 | **示例 2** 33 | 34 | ``` 35 | 输入:grid = [[1,2,3],[4,5,6]] 36 | 输出:12 37 | ``` 38 | 39 | **约束条件:** 40 | 41 | - `m == grid.length` 42 | - `n == grid[i].length` 43 | - `1 <= m, n <= 200` 44 | - `0 <= grid[i][j] <= 100` 45 | 46 | ## 3. 答案 47 | 48 | ```swift 49 | class MinimumPathSum { 50 | func minPathSum(_ grid: [[Int]]) -> Int { 51 | guard grid.count != 0 && grid[0].count != 0 else{ 52 | return 0 53 | } 54 | 55 | let m = grid.count, n = grid[0].count 56 | var dp = Array(repeating: Array(repeating: 0, count: n), count: m) 57 | 58 | for i in 0.. 难度水平:困难 10 | 11 | ## 1. 描述 12 | 13 | 给出集合 `[1,2,3,...,n]`,其所有元素共有 `n!` 种排列。 14 | 15 | 按大小顺序列出所有排列情况,并一一标记,当 `n = 3` 时, 所有排列如下: 16 | 17 | 1. `"123"` 18 | 2. `"132"` 19 | 3. `"213"` 20 | 4. `"231"` 21 | 5. `"312"` 22 | 6. `"321"` 23 | 24 | 给定 `n` 和 `k`,返回第 `k` 个排列。 25 | 26 | ## 2. 示例 27 | 28 | **示例 1** 29 | 30 | ``` 31 | 输入:n = 3, k = 3 32 | 输出:"213" 33 | ``` 34 | 35 | **示例 2** 36 | 37 | ``` 38 | 输入:n = 4, k = 9 39 | 输出:"2314" 40 | ``` 41 | 42 | **示例 3** 43 | 44 | ``` 45 | 输入:n = 3, k = 1 46 | 输出:"123" 47 | ``` 48 | 49 | **约束条件:** 50 | 51 | - `1 <= n <= 9` 52 | - `1 <= k <= n!` 53 | 54 | ## 3. 答案 55 | 56 | ```swift 57 | class PermutationSequence { 58 | func getPermutation(_ n: Int, _ k: Int) -> String { 59 | var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] 60 | 61 | var factorial = 1 62 | for i in 1 ..< n { 63 | factorial *= i 64 | } 65 | 66 | var result = "" 67 | var k = k 68 | var divisor = n - 1 69 | 70 | for i in 0 ..< n { 71 | for (index, number) in numbers.enumerated() { 72 | if k > factorial { 73 | k -= factorial 74 | } else { 75 | result += "\(number)" 76 | numbers.remove(at: index) 77 | break 78 | } 79 | } 80 | if divisor > 1 { 81 | factorial /= divisor 82 | divisor -= 1 83 | } 84 | } 85 | 86 | return result 87 | } 88 | } 89 | ``` 90 | 91 | * 主要思想:迭代并将数组从最后一个更改为第一个。 92 | * 时间复杂度: O(n^2) 93 | * 空间复杂度: O(1) 94 | 95 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 96 | 97 | 点击前往 [LeetCode](https://leetcode.com/problems/permutation-sequence/ "LeetCode") 练习 98 | 99 | ## 关于我们 100 | 101 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 102 | 103 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 104 | -------------------------------------------------------------------------------- /LeetCode/#47 全排列 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 46 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个可包含重复数字的序列 `nums` ,**按任意顺序** 返回所有不重复的全排列。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:nums = [1,1,2] 23 | 输出: 24 | [[1,1,2], 25 | [1,2,1], 26 | [2,1,1]] 27 | ``` 28 | 29 | **示例 2** 30 | 31 | ``` 32 | 输入:nums = [1,2,3] 33 | 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 34 | ``` 35 | 36 | **约束条件:** 37 | 38 | - `1 <= nums.length <= 8` 39 | - `-10 <= nums[i] <= 10` 40 | 41 | ## 3. 答案 42 | 43 | ```swift 44 | class PermutationsII { 45 | func permuteUnique(_ nums: [Int]) -> [[Int]] { 46 | var res = [[Int]](), path = [Int](), visited = [Bool](repeating: false, count: nums.count) 47 | 48 | let nums = nums.sorted(by: <) 49 | 50 | _dfs(&res, &path, nums, &visited) 51 | 52 | return res 53 | } 54 | 55 | private func _dfs(inout res: [[Int]], inout _ path: [Int], _ nums: [Int], inout _ visited: [Bool]) { 56 | // termination case 57 | if path.count == nums.count { 58 | res.append(path) 59 | return 60 | } 61 | 62 | for i in 0.. 0 && nums[i] == nums[i - 1] && visited[i - 1]) { 64 | continue 65 | } 66 | 67 | path.append(nums[i]) 68 | visited[i] = true 69 | _dfs(&res, &path, nums, &visited) 70 | visited[i] = false 71 | path.removeLast() 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | * 主要思想:经典深度优先搜索,采用最后出现避免重复。 78 | * 时间复杂度: O(n^n) 79 | * 空间复杂度: O(n) 80 | 81 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 82 | 83 | 点击前往 [LeetCode](https://leetcode.com/problems/permutations-ii/ "LeetCode") 练习 84 | 85 | ## 关于我们 86 | 87 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 88 | 89 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 90 | -------------------------------------------------------------------------------- /LeetCode/#11 盛最多水的容器.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 给定 `n` 个非负整数 `a1, a2, ..., an` ,其中每个代表坐标 `(i, ai)` 处的一个点。 绘制 `n` 条垂直线,使得线 `i` 的两个端点位于 `(i, ai)` 和 `(i, 0)`。 找出两条线,它们与 `x` 轴一起形成一个容器,这样容器中的水最多。 13 | 14 | **注意**:不能倾斜容器。 15 | 16 | ## 2. 示例 17 | 18 | **示例 1** 19 | ![示例 1](https://github.com/SwiftCommunityRes/LeetCode--Swift/question_11.jpeg) 20 | ``` 21 | 输入: height = [1,8,6,2,5,4,8,3,7] 22 | 输出: 49 23 | 说明: 上述垂直线由数组 [1,8,6,2,5,4,8,3,7] 表示。 在这种情况下,容器可以容纳的最大水面积(蓝色部分)为 49。 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入: height = [1,1] 30 | 输出: 1 31 | ``` 32 | 33 | **示例 3** 34 | 35 | ``` 36 | 输入: height = [4,3,2,1,4] 37 | 输出: 16 38 | ``` 39 | 40 | **示例 4** 41 | 42 | ``` 43 | 输入: height = [1,2,1] 44 | 输出: 2 45 | ``` 46 | 47 | **约束条件:** 48 | - n == height.length 49 | - 2 <= n <= 10^5 50 | - 0 <= height[i] <= 10^4 51 | 52 | 53 | ## 3. 答案 54 | 55 | ```swift 56 | class ContainerMostWater { 57 | func maxArea(_ height: [Int]) -> Int { 58 | var maxRes = 0 59 | var left = 0 60 | var right = height.count - 1 61 | 62 | while left < right { 63 | let minHeight = min(height[left], height[right]) 64 | 65 | maxRes = max(maxRes, (right - left) * minHeight) 66 | 67 | if minHeight == height[left] { 68 | left += 1 69 | } else { 70 | right -= 1 71 | } 72 | } 73 | 74 | return maxRes 75 | } 76 | } 77 | ``` 78 | 79 | * 主要思想:首先给定最大宽度,然后在宽度减小的同时,向高度增加方向前进。 80 | * 时间复杂度: O(n) 81 | * 空间复杂度: O(1) 82 | 83 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 84 | 85 | 点击前往 [LeetCode](https://leetcode.com/problems/container-with-most-water/ "LeetCode") 练习 86 | 87 | ## 关于我们 88 | 89 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 90 | 91 | Swift社区 92 | -------------------------------------------------------------------------------- /LeetCode/#59 螺旋矩阵 II.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 58 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给你一个正整数 `n` ,生成一个包含 `1` 到 `n2` 所有元素,且元素按顺时针顺序螺旋排列的 `n x n` 正方形矩阵 `matrix` 。 14 | 15 | ## 2. 示例 16 | 17 | **示例 1** 18 | 19 | ``` 20 | 输入:n = 3 21 | 输出:[[1,2,3],[8,9,4],[7,6,5]] 22 | ``` 23 | 24 | **示例 2** 25 | 26 | ``` 27 | 输入:n = 1 28 | 输出:[[1]] 29 | ``` 30 | 31 | **约束条件:** 32 | 33 | - `1 <= n <= 20` 34 | 35 | ## 3. 答案 36 | 37 | ```swift 38 | class SpiralMatrixII { 39 | func generateMatrix(_ n: Int) -> [[Int]] { 40 | guard n > 0 else { 41 | return [[Int]]() 42 | } 43 | 44 | var num = 1 45 | var res = Array(repeating: Array(repeating: 0, count: n), count: n) 46 | 47 | for layer in 0.. 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,**只能进行节点交换**)。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ![image](https://upload-images.jianshu.io/upload_images/2829694-8a9584ea0c71c357.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 22 | 23 | ``` 24 | 输入:head = [1,2,3,4] 25 | 输出:[2,1,4,3] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:head = [] 32 | 输出:[] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:head = [1] 39 | 输出:[1] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - 链表中节点的数目在范围 `[0, 100]` 内 45 | - `0 <= Node.val <= 100` 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | /** 51 | * Definition for singly-linked list. 52 | * struct ListNode { 53 | * int val; 54 | * ListNode *next; 55 | * ListNode() : val(0), next(nullptr) {} 56 | * ListNode(int x) : val(x), next(nullptr) {} 57 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 58 | * }; 59 | */ 60 | class SwapNodesInPairs { 61 | func swapPairs(head: ListNode?) -> ListNode? { 62 | let dummy = ListNode(0) 63 | dummy.next = head 64 | 65 | var prev: ListNode? = dummy 66 | var current = dummy.next 67 | 68 | while current != nil && current!.next != nil { 69 | let next = current!.next 70 | let post = current!.next!.next 71 | 72 | prev!.next = next 73 | next!.next = current 74 | current!.next = post 75 | 76 | prev = current 77 | current = post 78 | } 79 | 80 | return dummy.next 81 | } 82 | } 83 | ``` 84 | 85 | * 主要思想:三个指针,每次改变指针的方向。 86 | * 时间复杂度: O(n) 87 | * 空间复杂度: O(1) 88 | 89 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 90 | 91 | 点击前往 [LeetCode](https://leetcode.com/problems/swap-nodes-in-pairs/ "LeetCode") 练习 92 | 93 | ## 关于我们 94 | 95 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 96 | 97 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 98 | -------------------------------------------------------------------------------- /LeetCode/#88 合并有序数组.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 给定两个非递减整数数组 `nums1` 和 `nums2`,以及两个整数 `m` 和 `n`,分别表示 `nums1` 和 `nums2` 中的元素数目。 15 | 16 | 合并数组 `nums1` 和 `nums2` 进一个单独的非递减数组中。 17 | 18 | 最终排序的数组不要被函数返回,而是被存储在 `nums1` 中。为了适应这个要求,`nums1` 的长度为 `m + n`,`nums1` 的前 `m` 个元素是需要被合并的,而后面的 `n` 个元素被设置为 `0` 并且要被忽略(不被合并)。数字 `nums2` 长度为 `n`。 19 | 20 | ## 2. 示例 21 | 22 | **示例 1** 23 | 24 | ``` 25 | 输入: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 26 | 输出: [1,2,2,3,5,6] 27 | 解释: 我们正在合并的数组为 [1,2,3] 和 [2,5,6]。合并后的结果为 [1,2,2,3,5,6] 下划线的元素来自于 nums1。 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入: nums1 = [1], m = 1, nums2 = [], n = 0 34 | 输出: [1] 35 | 解释: 我们正在合并的数组为 [1] 和 []。合并后的结果为 [1]。 36 | ``` 37 | 38 | **示例 3** 39 | 40 | ``` 41 | 输入: nums1 = [0], m = 0, nums2 = [1], n = 1 42 | 输出: [1] 43 | 解释: 我们正在合并的数组为 [] 和 [1]。合并后的结果为 [1]。注意,由于 m = 0,nums1 中不存在元素。0 只是存在那以保证合并后的结果能够与 nums1 相适应。 44 | ``` 45 | 46 | **约束条件** 47 | 48 | - `nums1.length == m + n` 49 | - `nums2.length == n` 50 | - `0 <= m, n <= 200` 51 | - `1 <= m + n <= 200` 52 | - `-109 <= nums1[i], nums2[j] <= 109` 53 | 54 | **后续** 55 | 你是否能找到一个时间复杂度为 `O(m + n)` 运行的算法? 56 | 57 | ## 3. 答案 58 | 59 | ```swift 60 | class MergeSortedArray { 61 | func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) { 62 | var i = m - 1, j = n - 1 63 | 64 | while i >= 0 || j >= 0 { 65 | if j < 0 || (i >= 0 && nums1[i] > nums2[j]) { 66 | nums1[i + j + 1] = nums1[i] 67 | i -= 1 68 | } else { 69 | nums1[i + j + 1] = nums2[j] 70 | j -= 1 71 | } 72 | } 73 | } 74 | } 75 | 76 | ``` 77 | 78 | * 主要思想:从尾部道头部合并数组,以避免被重载。 79 | * 时间复杂度: O(n) 80 | * 空间复杂度: O(1) 81 | 82 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 83 | 84 | 点击前往 [LeetCode](https://leetcode.com/problems/merge-sorted-array/ "LeetCode") 练习 85 | 86 | ## 关于我们 87 | 88 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 89 | 90 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 91 | -------------------------------------------------------------------------------- /LeetCode/#28 实现 strStr().md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 27 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 实现 `strStr()` 函数。 16 | 17 | 给你两个字符串 `haystack` 和 `needle`,请你在 `haystack` 字符串中找出 `needle` 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 `-1` 。 18 | 19 | **说明:** 20 | 21 | 当 `needle` 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 22 | 23 | 对于本题而言,当 `needle` 是空字符串时我们应当返回 0 。这与 C 语言的 `strstr()` 以及 Java 的 `indexOf()` 定义相符。 24 | 25 | ## 2. 示例 26 | 27 | **示例 1** 28 | 29 | ``` 30 | 输入:haystack = "hello", needle = "ll" 31 | 输出:2 32 | ``` 33 | 34 | **示例 2** 35 | 36 | ``` 37 | 输入:haystack = "aaaaa", needle = "bba" 38 | 输出:-1 39 | ``` 40 | 41 | **示例 3** 42 | 43 | ``` 44 | 输入:haystack = "", needle = "" 45 | 输出:0 46 | ``` 47 | 48 | **约束条件:** 49 | 50 | - `0 <= haystack.length, needle.length <= 5 * 10^4` 51 | - `haystack` 和 `needle` 仅由小写英文字符组成 52 | 53 | ## 3. 答案 54 | 55 | ```swift 56 | class StrStr { 57 | func strStr(_ haystack: String, _ needle: String) -> Int { 58 | let hChars = Array(haystack.characters), nChars = Array(needle.characters) 59 | let hLen = hChars.count, nLen = nChars.count 60 | 61 | guard hLen >= nLen else { 62 | return -1 63 | } 64 | guard nLen != 0 else { 65 | return 0 66 | } 67 | 68 | for i in 0...hLen - nLen { 69 | if hChars[i] == nChars[0] { 70 | for j in 0.. 难度水平:困难 10 | 11 | ## 1. 描述 12 | 13 | 给你一个链表的头节点 `head` ,旋转链表,将链表每个节点向右移动 `k` 个位置。 14 | 15 | ## 2. 示例 16 | 17 | **示例 1** 18 | 19 | ``` 20 | 输入:head = [1,2,3,4,5], k = 2 21 | 输出:[4,5,1,2,3] 22 | ``` 23 | 24 | **示例 2** 25 | 26 | ``` 27 | 输入:head = [0,1,2], k = 4 28 | 输出:[2,0,1] 29 | ``` 30 | 31 | **约束条件:** 32 | 33 | - 链表中节点的数目在范围 `[0, 500]` 内 34 | - `-100 <= Node.val <= 100` 35 | - `0 <= k <= 2 * 10^9` 36 | 37 | ## 3. 答案 38 | 39 | ```swift 40 | /** 41 | * Definition for singly-linked list. 42 | * public class ListNode { 43 | * public var val: Int 44 | * public var next: ListNode? 45 | * public init(_ val: Int) { 46 | * self.val = val 47 | * self.next = nil 48 | * } 49 | * } 50 | */ 51 | 52 | class RotateList { 53 | func rotateRight(head: ListNode?, _ k: Int) -> ListNode? { 54 | if head == nil { 55 | return head 56 | } 57 | 58 | var prev = head 59 | var post = head 60 | let len = _getLength(head) 61 | var k = k % len 62 | 63 | while k > 0 { 64 | post = post!.next 65 | k -= 1 66 | } 67 | 68 | while post!.next != nil { 69 | prev = prev!.next 70 | post = post!.next 71 | } 72 | 73 | post!.next = head 74 | post = prev!.next 75 | prev!.next = nil 76 | 77 | return post 78 | } 79 | 80 | private func _getLength(head: ListNode?) -> Int { 81 | var len = 0 82 | var node = head 83 | 84 | while node != nil { 85 | len += 1 86 | node = node!.next 87 | } 88 | 89 | return len 90 | } 91 | } 92 | ``` 93 | 94 | * 主要思想:Runner Tech。 95 | * 时间复杂度: O(n) 96 | * 空间复杂度: O(1) 97 | 98 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 99 | 100 | 点击前往 [LeetCode](https://leetcode.com/problems/rotate-list/ "LeetCode") 练习 101 | 102 | ## 关于我们 103 | 104 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 105 | 106 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 -------------------------------------------------------------------------------- /LeetCode/#56 合并区间(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 55 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 以数组 `intervals` 表示若干个区间的集合,其中单个区间为 `intervals[i] = [starti, endi]` 。请你合并所有重叠的区间,并返回 *一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间* 。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 23 | 输出:[[1,6],[8,10],[15,18]] 24 | 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入:intervals = [[1,4],[4,5]] 31 | 输出:[[1,5]] 32 | 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。 33 | ``` 34 | 35 | **约束条件:** 36 | 37 | - `1 <= intervals.length <= 10^4` 38 | - `intervals[i].length == 2` 39 | - `0 <= starti <= endi <= 10^4` 40 | 41 | ## 3. 答案 42 | 43 | ```swift 44 | /** 45 | * Definition for an interval. 46 | * public class Interval { 47 | * public var start: Int 48 | * public var end: Int 49 | * public init(_ start: Int, _ end: Int) { 50 | * self.start = start 51 | * self.end = end 52 | * } 53 | * } 54 | */ 55 | class MergeIntervals { 56 | func merge(intervals: [Interval]) -> [Interval] { 57 | var result = [Interval]() 58 | 59 | let intervals = intervals.sorted { 60 | if $0.start != $1.start { 61 | return $0.start < $1.start 62 | } else { 63 | return $0.end < $1.end 64 | } 65 | } 66 | 67 | for interval in intervals { 68 | guard let last = result.last else { 69 | result.append(interval) 70 | continue 71 | } 72 | 73 | if last.end < interval.start { 74 | result.append(interval) 75 | } else { 76 | last.end = max(last.end, interval.end) 77 | } 78 | } 79 | 80 | return result 81 | } 82 | } 83 | ``` 84 | 85 | * 主要思想:对原始的间隔进行排序,然后一个接一个地添加它们。 86 | * 时间复杂度: O(nlogn) 87 | * 空间复杂度: O(n) 88 | 89 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 90 | 91 | 点击前往 [LeetCode](https://leetcode.com/problems/merge-intervals/ "LeetCode") 练习 92 | 93 | ## 关于我们 94 | 95 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 96 | 97 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 98 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /LeetCode/#26 删除有序数组中的重复项.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 25 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给你一个 **升序排列** 的数组 `nums` ,请你 `原地` 删除重复出现的元素,使每个元素 **只出现一次** ,返回删除后数组的新长度。元素的 **相对顺序** 应该保持 **一致** 。 16 | 17 | 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组 nums 的第一部分。更规范地说,如果在删除重复项之后有 `k` 个元素,那么 `nums` 的前 `k` 个元素应该保存最终结果。 18 | 19 | 将最终结果插入 `nums` 的前 `k` 个位置后返回 `k` 。 20 | 21 | 不要使用额外的空间,你必须在 `原地` **修改输入数组** 并在使用 O(1) 额外空间的条件下完成。 22 | 23 | **判题标准:** 24 | 25 | 系统会用下面的代码来测试你的题解: 26 | 27 | ``` 28 | int[] nums = [...]; // 输入数组 29 | int[] expectedNums = [...]; // 长度正确的期望答案 30 | 31 | int k = removeDuplicates(nums); // 调用 32 | 33 | assert k == expectedNums.length; 34 | for (int i = 0; i < k; i++) { 35 | assert nums[i] == expectedNums[i]; 36 | } 37 | ``` 38 | 39 | 如果所有断言都通过,那么您的题解将被 **通过**。 40 | 41 | ## 2. 示例 42 | 43 | **示例 1** 44 | 45 | ``` 46 | 输入:nums = [1,1,2] 47 | 输出:2, nums = [1,2,_] 48 | 解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。 49 | ``` 50 | 51 | **示例 2** 52 | 53 | ``` 54 | 输入:nums = [0,0,1,1,1,2,2,3,3,4] 55 | 输出:5, nums = [0,1,2,3,4] 56 | 解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。 57 | ``` 58 | 59 | **约束条件:** 60 | 61 | - `0 <= nums.length <= 3 * 10^4` 62 | - `-10^4 <= nums[i] <= 10^4` 63 | - `nums` 已按 **升序** 排列 64 | 65 | ## 3. 答案 66 | 67 | ```swift 68 | class RemoveDuplicatesFromSortedArray { 69 | func removeDuplicates(inout nums: [Int]) -> Int { 70 | guard nums.count > 0 else { 71 | return 0 72 | } 73 | 74 | var index = 0 75 | 76 | for num in nums where num != nums[index] { 77 | index += 1 78 | nums[index] = num 79 | } 80 | 81 | return index + 1 82 | } 83 | } 84 | ``` 85 | 86 | * 主要思想:保留一个索引,将该索引处的元素与前面的元素进行比较。 87 | * 时间复杂度: O(n) 88 | * 空间复杂度: O(1) 89 | 90 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 91 | 92 | 点击前往 [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-array/ "LeetCode") 练习 93 | 94 | ## 关于我们 95 | 96 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 97 | 98 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 99 | -------------------------------------------------------------------------------- /LeetCode/#35 搜索插入位置.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 34 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 16 | 17 | 请必须使用时间复杂度为 `O(log n)` 的算法。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入: nums = [1,3,5,6], target = 5 25 | 输出: 2 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入: nums = [1,3,5,6], target = 2 32 | 输出: 1 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入: nums = [1,3,5,6], target = 7 39 | 输出: 4 40 | ``` 41 | 42 | **示例 4** 43 | 44 | ``` 45 | 输入: nums = [1,3,5,6], target = 0 46 | 输出: 0 47 | ``` 48 | 49 | **示例 5** 50 | 51 | ``` 52 | 输入: nums = [1], target = 0 53 | 输出: 0 54 | ``` 55 | 56 | **约束条件:** 57 | 58 | - `1 <= nums.length <= 10^4` 59 | - `-10^4 <= nums[i] <= 10^4` 60 | - `nums` 为无重复元素的升序排列数组 61 | - `-10^4 <= target <= 10^4` 62 | 63 | ## 3. 答案 64 | 65 | ```swift 66 | class SearchInsertPosition { 67 | func searchInsert(nums: [Int], _ target: Int) -> Int { 68 | guard nums.count > 0 else { 69 | return 0 70 | } 71 | 72 | var left = 0 73 | var right = nums.count - 1 74 | var mid = 0 75 | 76 | while left + 1 < right { 77 | mid = (right - left) / 2 + left 78 | if nums[mid] == target { 79 | return mid 80 | } else if nums[mid] < target { 81 | left = mid 82 | } else { 83 | right = mid 84 | } 85 | } 86 | 87 | if nums[right] < target { 88 | return right + 1 89 | } 90 | if nums[left] >= target { 91 | return left 92 | } 93 | 94 | return right 95 | } 96 | } 97 | ``` 98 | 99 | * 主要思想:二分搜索,直到剩下两个变量。 100 | * 时间复杂度: O(logn) 101 | * 空间复杂度: O(1) 102 | 103 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 104 | 105 | 点击前往 [LeetCode](https://leetcode.com/problems/search-insert-position/ "LeetCode") 练习 106 | 107 | ## 关于我们 108 | 109 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 110 | 111 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 112 | -------------------------------------------------------------------------------- /LeetCode/#42 接雨水(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 41 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:困难 14 | 15 | ## 1. 描述 16 | 17 | 给定 `n` 个非负整数表示每个宽度为 `1` 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ![](https://files.mdnice.com/user/17787/aeddc90f-ab5d-4f92-99d9-8b4fc21ea838.png) 24 | 25 | ``` 26 | 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 27 | 输出:6 28 | 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入:height = [4,2,0,3,2,5] 35 | 输出:9 36 | ``` 37 | 38 | **约束条件:** 39 | 40 | - `n == height.length` 41 | - `1 <= n <= 2 * 10^4` 42 | - `0 <= height[i] <= 10^5` 43 | 44 | ## 3. 答案 45 | 46 | ```swift 47 | class TrappingRainWater { 48 | func trap(height: [Int]) -> Int { 49 | guard height.count > 0 else { 50 | return 0 51 | } 52 | 53 | var res = 0 54 | var left = _initMaxHeights(height, true) 55 | var right = _initMaxHeights(height, false) 56 | 57 | for i in 0.. [Int] { 65 | var res = [Int](count: height.count, repeatedValue: 0) 66 | var currentMax = 0 67 | 68 | if isLeft { 69 | for i in 0.. 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | **n 皇后问题** 研究的是如何将 `n` 个皇后放置在 `n × n` 的棋盘上,并且使皇后彼此之间不能相互攻击。 16 | 17 | 给你一个整数 `n` ,返回 **n 皇后问题** 不同的解决方案的数量。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:n = 4 25 | 输出:2 26 | 解释:如上图所示,4 皇后问题存在两个不同的解法。 27 | ``` 28 | 29 | **示例 2** 30 | 31 | ``` 32 | 输入:n = 1 33 | 输出:1 34 | ``` 35 | 36 | **约束条件:** 37 | 38 | - `1 <= n <= 9` 39 | 40 | ## 3. 答案 41 | 42 | ```swift 43 | class NQueensII { 44 | func totalNQueens(_ n: Int) -> Int { 45 | guard n > 0 else { 46 | return 0 47 | } 48 | var count = 0 49 | var usedCols = Array(repeating: 0, count: n) 50 | 51 | dfs(&usedCols, &count, n, 0) 52 | 53 | return count 54 | } 55 | 56 | private func dfs(_ usedCols: inout [Int], _ count: inout Int, _ n: Int, _ row: Int) { 57 | if row == n { 58 | count += 1 59 | return 60 | } 61 | 62 | for col in 0.. Bool { 71 | var c = -1 72 | 73 | for i in 0.. 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给定两个整数,被除数 `dividend` 和除数 `divisor`。将两数相除,要求不使用乘法、除法和 mod 运算符。 16 | 17 | 返回被除数 `dividend` 除以除数 `divisor` 得到的商。 18 | 19 | 整数除法的结果应当截去(`truncate`)其小数部分,例如:`truncate(8.345) = 8` 以及 `truncate(-2.7335) = -2`。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入: dividend = 10, divisor = 3 27 | 输出: 3 28 | 解释: 10/3 = truncate(3.33333..) = truncate(3) = 3 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入: dividend = 7, divisor = -3 35 | 输出: -2 36 | 解释: 7/-3 = truncate(-2.33333..) = -2 37 | ``` 38 | 39 | **约束条件:** 40 | 41 | - 被除数和除数均为 `32` 位有符号整数。 42 | - 除数不为 `0`。 43 | - 假设我们的环境只能存储 `32` 位有符号整数,其数值范围是 `[−231, 231 − 1]`。本题中,如果除法结果溢出,则返回 2^31 − 1。 44 | 45 | ## 3. 答案 46 | 47 | ```swift 48 | class DivideTwoIntegers { 49 | func divide(_ dividend: Int, _ divisor: Int) -> Int { 50 | let isPositive = (dividend < 0) == (divisor < 0) 51 | var dividend = abs(dividend), divisor = abs(divisor), count = 0 52 | 53 | while dividend >= divisor { 54 | var shift = 0 55 | 56 | while dividend >= (divisor << shift) { 57 | shift += 1 58 | } 59 | 60 | dividend -= divisor << (shift - 1) 61 | 62 | count += (1 << (shift - 1)) 63 | } 64 | 65 | return refactorCount(count, isPositive) 66 | } 67 | 68 | private func refactorCount(_ count: Int, _ isPositive: Bool) -> Int { 69 | let INTMAX = 2147483647 70 | var count = count 71 | 72 | if isPositive { 73 | if count > INTMAX { 74 | count = INTMAX 75 | } 76 | } else { 77 | count *= -1 78 | } 79 | 80 | return count 81 | } 82 | } 83 | ``` 84 | 85 | * 主要思想:使用左移和减法得到每个数字的个数。 86 | * 时间复杂度: O(logn) 87 | * 空间复杂度: O(1) 88 | 89 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 90 | 91 | 点击前往 [LeetCode](https://leetcode.com/problems/divide-two-integers/ "LeetCode") 练习 92 | 93 | ## 关于我们 94 | 95 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 96 | 97 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 98 | -------------------------------------------------------------------------------- /LeetCode/#40 组合总和 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 39 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个候选人编号的集合 `candidates` 和一个目标数 `target` ,找出 `candidates` 中所有可以使数字和为 `target` 的组合。 16 | 17 | `candidates` 中的每个数字在每个组合中只能使用 **一次** 。 18 | 19 | **注意:** 解集不能包含重复的组合。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入: candidates = [10,1,2,7,6,1,5], target = 8, 27 | 输出: 28 | [ 29 | [1,1,6], 30 | [1,2,5], 31 | [1,7], 32 | [2,6] 33 | ] 34 | ``` 35 | 36 | **示例 2** 37 | 38 | ``` 39 | 输入: candidates = [2,5,2,1,2], target = 5, 40 | 输出: 41 | [ 42 | [1,2,2], 43 | [5] 44 | ] 45 | ``` 46 | 47 | **约束条件:** 48 | 49 | - `1 <= candidates.length <= 100` 50 | - `1 <= candidates[i] <= 50` 51 | - `1 <= target <= 30` 52 | 53 | ## 3. 答案 54 | 55 | ```swift 56 | class CombinationSumII { 57 | func combinationSum2(candidates: [Int], _ target: Int) -> [[Int]] { 58 | var res = [[Int]](), path = [Int]() 59 | 60 | dfs(&res, &path, target, candidates.sorted(), 0) 61 | 62 | return res 63 | } 64 | 65 | fileprivate func dfs(_ res: inout [[Int]], _ path: inout [Int], _ target: Int, _ candidates: [Int], _ index: Int) { 66 | if target == 0 { 67 | res.append(Array(path)) 68 | return 69 | } 70 | 71 | for i in index.. 0 && candidates[i] == candidates[i - 1] && i != index { 77 | continue 78 | } 79 | 80 | path.append(candidates[i]) 81 | _dfs(&res, &path, target - candidates[i], candidates, i + 1) 82 | path.removeLast() 83 | } 84 | } 85 | } 86 | ``` 87 | 88 | * 主要思想:经典的深度优先搜索。 89 | * 时间复杂度: O(n^n) 90 | * 空间复杂度: O(2^n - 2) 91 | 92 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 93 | 94 | 点击前往 [LeetCode](https://leetcode.com/problems/combination-sum-ii/ "LeetCode") 练习 95 | 96 | ## 关于我们 97 | 98 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 99 | 100 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 101 | -------------------------------------------------------------------------------- /LeetCode/#80 删除有序数组中的重复项 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 79 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给你一个有序数组 `nums` ,请你 **原地** 删除重复出现的元素,使每个元素 **最多出现两次** ,返回删除后数组的新长度。 16 | 17 | 不要使用额外的数组空间,你必须在 `原地` **修改输入数组** 并在使用 O(1) 额外空间的条件下完成。 18 | 19 | **说明:** 20 | 21 | 为什么返回数值是整数,但输出的答案是数组呢? 22 | 23 | 请注意,输入数组是以 **「引用」** 方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 24 | 25 | 你可以想象内部操作如下: 26 | 27 | ``` 28 | // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 29 | int len = removeDuplicates(nums); 30 | 31 | // 在函数里修改输入数组对于调用者是可见的。 32 | // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 33 | for (int i = 0; i < len; i++) { 34 | print(nums[i]); 35 | } 36 | ``` 37 | 38 | ## 2. 示例 39 | 40 | **示例 1** 41 | 42 | ``` 43 | 输入:nums = [1,1,1,2,2,3] 44 | 输出:5, nums = [1,1,2,2,3] 45 | 解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。 46 | ``` 47 | 48 | **示例 2** 49 | 50 | ``` 51 | 输入:nums = [0,0,1,1,1,1,2,3,3] 52 | 输出:7, nums = [0,0,1,1,2,3,3] 53 | 解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。 54 | ``` 55 | 56 | **约束条件:** 57 | 58 | - `1 <= nums.length <= 3 * 10^4` 59 | - `-10^4 <= nums[i] <= 10^4` 60 | - `nums` 已按升序排列 61 | 62 | ## 3. 答案 63 | 64 | ```swift 65 | class RemoveDuplicatesFromSortedArrayII { 66 | func removeDuplicates(inout nums: [Int]) -> Int { 67 | guard nums.count > 2 else { 68 | return nums.count 69 | } 70 | 71 | var index = 1 72 | 73 | for i in 2.. 98 | -------------------------------------------------------------------------------- /LeetCode/#19 删除链表的倒数第 N 个结点.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 18 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 14 | 15 | ## 2. 示例 16 | 17 | **示例 1** 18 | 19 | ``` 20 | 输入:head = [1,2,3,4,5], n = 2 21 | 输出:[1,2,3,5] 22 | ``` 23 | 24 | **示例 2** 25 | 26 | ``` 27 | 输入:head = [1], n = 1 28 | 输出:[] 29 | ``` 30 | 31 | **示例 3** 32 | 33 | ``` 34 | 输入:head = [1,2], n = 1 35 | 输出:[1] 36 | ``` 37 | 38 | **约束条件:** 39 | 40 | - 链表中结点的数目为 `sz` 41 | - `1 <= sz <= 30` 42 | - `0 <= Node.val <= 100` 43 | - `1 <= n <= sz` 44 | 45 | ## 3. 答案 46 | 47 | ```swift 48 | class RemoveNthFromEnd { 49 | func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? { 50 | let dummy = ListNode(0) 51 | dummy.next = head 52 | var prev: ListNode? = dummy 53 | var post: ListNode? = dummy 54 | 55 | // move post 56 | for _ in 0.. 88 | 89 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 90 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 91 | 92 | 93 | -------------------------------------------------------------------------------- /LeetCode/#63 不同路径 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 62 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 一个机器人位于一个 `m x n` 网格的左上角 (起始点在下图中标记为 “Start” )。 16 | 17 | 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 18 | 19 | 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 20 | 21 | 网格中的障碍物和空位置分别用 `1` 和 `0` 来表示。 22 | 23 | ## 2. 示例 24 | 25 | **示例 1** 26 | 27 | ``` 28 | 输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]] 29 | 输出:2 30 | 解释:3x3 网格的正中间有一个障碍物。 31 | 从左上角到右下角一共有 2 条不同的路径: 32 | 1. 向右 -> 向右 -> 向下 -> 向下 33 | 2. 向下 -> 向下 -> 向右 -> 向右 34 | ``` 35 | 36 | **示例 2** 37 | 38 | 39 | ``` 40 | 输入:obstacleGrid = [[0,1],[0,0]] 41 | 输出:1 42 | ``` 43 | 44 | **约束条件:** 45 | 46 | - `m == obstacleGrid.length` 47 | - `n == obstacleGrid[i].length` 48 | - `1 <= m, n <= 100` 49 | - `obstacleGrid[i][j]` 为 `0` 或 `1` 50 | 51 | ## 3. 答案 52 | 53 | ```swift 54 | class UniquePathsII { 55 | func uniquePathsWithObstacles(_ obstacleGrid: [[Int]]) -> Int { 56 | let m = obstacleGrid.count 57 | guard m > 0 else { 58 | return 0 59 | } 60 | 61 | let n = obstacleGrid[0].count 62 | guard n > 0 else { 63 | return 0 64 | } 65 | 66 | var dp = Array(repeating: Array(repeating: -1, count: n), count: m) 67 | 68 | return help(m - 1, n - 1, &dp, obstacleGrid) 69 | } 70 | 71 | fileprivate func help(_ m: Int, _ n: Int, _ dp: inout [[Int]], _ obstacleGrid: [[Int]]) -> Int { 72 | if m < 0 || n < 0 { 73 | return 0 74 | } 75 | if obstacleGrid[m][n] == 1 { 76 | return 0 77 | } 78 | if m == 0 && n == 0 { 79 | return 1 80 | } 81 | if dp[m][n] != -1 { 82 | return dp[m][n] 83 | } 84 | 85 | dp[m][n] = help(m - 1, n, &dp, obstacleGrid) + help(m, n - 1, &dp, obstacleGrid) 86 | return dp[m][n] 87 | } 88 | } 89 | ``` 90 | 91 | * 主要思想:2D动态编程,使用2D数组作为缓存来存储计算数据。 92 | * 时间复杂度: O(mn) 93 | * 空间复杂度: O(mn) 94 | 95 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 96 | 97 | 点击前往 [LeetCode](https://leetcode.com/problems/unique-paths-ii/ "LeetCode") 练习 98 | 99 | ## 关于我们 100 | 101 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 102 | 103 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 104 | -------------------------------------------------------------------------------- /LeetCode/#22 括号生成(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 21 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 数字 `n` 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 **有效的** 括号组合。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:n = 3 23 | 输出:["((()))","(()())","(())()","()(())","()()()"] 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入:n = 1 30 | 输出:["()"] 31 | ``` 32 | 33 | **约束条件:** 34 | 35 | - `1 <= n <= 8` 36 | 37 | ## 3. 答案 38 | 39 | ```swift 40 | class GenerateParentheses { 41 | func generateParenthesis(_ n: Int) -> [String] { 42 | guard n > 0 else { 43 | return [String]() 44 | } 45 | 46 | var paths = [String](), path = "" 47 | 48 | dfs(&paths, path, n, n) 49 | 50 | return paths 51 | } 52 | 53 | private func dfs(_ paths: inout [String], _ path: String, _ leftRemaining: Int, _ rightRemaining: Int) { 54 | if rightRemaining == 0 { 55 | paths.append(path) 56 | return 57 | } 58 | 59 | if leftRemaining > 0 { 60 | dfs(&paths, path + "(", leftRemaining - 1, rightRemaining) 61 | } 62 | if rightRemaining > leftRemaining { 63 | dfs(&paths, path + ")", leftRemaining, rightRemaining - 1) 64 | } 65 | } 66 | } 67 | ``` 68 | 69 | * 主要思想:Dummy Node来遍历两个列表,比较两个节点并指向右边的一个。 70 | * 时间复杂度: O(2^n) 71 | * 空间复杂度: O(n) 72 | 73 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 74 | 75 | 点击前往 [LeetCode](https://leetcode.com/problems/generate-parentheses/ "LeetCode") 练习 76 | 77 | ## 关于我们 78 | 79 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 80 | 81 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 82 | 83 | Swift社区 84 | 85 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 86 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 87 | 88 | 89 | -------------------------------------------------------------------------------- /LeetCode/#82 删除排序链表中的重复元素 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 82 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个已排序的链表的头 `head` , *删除原始链表中所有重复数字的节点,只留下不同的数字* 。返回 **已排序的链表** 。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ![](https://images.xiaozhuanlan.com/photo/2022/f7f45eb209cb518e9a727c405072159c.png) 22 | 23 | ``` 24 | 输入:head = [1,2,3,3,4,4,5] 25 | 输出:[1,2,5] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ![](https://images.xiaozhuanlan.com/photo/2022/bd47a90525f8f00f28da1b82681ea789.png) 31 | 32 | ``` 33 | 输入:head = [1,1,1,2,3] 34 | 输出:[2,3] 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `链表中节点数目在范围 `[0, 300]` 内 40 | - `-100 <= Node.val <= 100` 41 | - 题目数据保证链表已经按升序 **排列** 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | /** 47 | * Definition for singly-linked list. 48 | * struct ListNode { 49 | * int val; 50 | * ListNode *next; 51 | * ListNode() : val(0), next(nullptr) {} 52 | * ListNode(int x) : val(x), next(nullptr) {} 53 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 54 | * }; 55 | */ 56 | class RemoveDuplicatesfromSortedListII { 57 | func deleteDuplicates(_ head: ListNode?) -> ListNode? { 58 | if head == nil || head!.next == nil { 59 | return head 60 | } 61 | 62 | let dummy = ListNode(0) 63 | dummy.next = head 64 | var node = dummy 65 | 66 | while node.next != nil && node.next!.next != nil { 67 | if node.next!.val == node.next!.next!.val { 68 | let val = node.next!.val 69 | while node.next != nil && node.next!.val == val { 70 | node.next = node.next!.next 71 | } 72 | } else { 73 | node = node.next! 74 | } 75 | } 76 | 77 | return dummy.next 78 | } 79 | } 80 | ``` 81 | 82 | * 主要思想:迭代列表,通过将next替换为next.next跳过重复项。 83 | * 时间复杂度: O(n) 84 | * 空间复杂度: O(1) 85 | 86 | > **注意:** Swift 提供了 "===" 来比较两个对象引用同一个引用 87 | 88 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 89 | 90 | 点击前往 [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ "LeetCode") 练习 91 | 92 | ## 关于我们 93 | 94 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 95 | 96 | Swift社区 97 | -------------------------------------------------------------------------------- /LeetCode/#39 组合总和(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长)**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 38 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给你一个 **无重复元素** 的整数数组 `candidates` 和一个目标整数 `target` ,找出 `candidates` 中可以使数字和为目标数 `target` 的 所有 **不同组合** ,并以列表形式返回。你可以按 **任意顺序** 返回这些组合。 18 | 19 | `candidates` 中的 **同一个** 数字可以 **无限制重复被选取** 。如果至少一个数字的被选数量不同,则两种组合是不同的。 20 | 21 | 对于给定的输入,保证和为 `target` 的不同组合数少于 `150` 个。 22 | 23 | ## 2. 示例 24 | **示例 1** 25 | 26 | ``` 27 | 输入:candidates = [2,3,6,7], target = 7 28 | 输出:[[2,2,3],[7]] 29 | 解释: 30 | 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 31 | 7 也是一个候选, 7 = 7 。 32 | 仅有这两种组合。 33 | ``` 34 | 35 | **示例 2** 36 | 37 | ``` 38 | 输入: candidates = [2,3,5], target = 8 39 | 输出: [[2,2,2,2],[2,3,3],[3,5]] 40 | ``` 41 | 42 | **示例 3** 43 | 44 | ``` 45 | 输入: candidates = [2], target = 1 46 | 输出: [] 47 | ``` 48 | 49 | **约束条件:** 50 | 51 | - `1 <= candidates.length <= 30` 52 | - `1 <= candidates[i] <= 200` 53 | - `candidate` 中的每个元素都 **互不相同** 54 | - `1 <= target <= 500` 55 | 56 | ## 3. 答案 57 | 58 | ```swift 59 | class CombinationSum { 60 | func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] { 61 | var combination = [Int](), combinations = [[Int]]() 62 | 63 | dfs(candidates.sorted(), target, 0, &combinations, &combination) 64 | 65 | return combinations 66 | } 67 | 68 | private func dfs(_ candidates: [Int], _ target: Int, _ index: Int, _ combinations: inout [[Int]], _ combination: inout [Int]) { 69 | if target == 0 { 70 | combinations.append(combination) 71 | return 72 | } 73 | 74 | for i in index.. 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个正整数 `n` ,输出外观数列的第 `n` 项。 16 | 17 | 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。 18 | 19 | 你可以将其视作是由递归公式定义的数字字符串序列: 20 | 21 | * `countAndSay(1) = "1"` 22 | * `countAndSay(n)` 是对 `countAndSay(n-1)` 的描述,然后转换成另一个数字字符串。 23 | 24 | **前五项如下:** 25 | 26 | ``` 27 | 1. 1 28 | 2. 11 29 | 3. 21 30 | 4. 1211 31 | 5. 111221 32 | 第一项是数字 1 33 | 描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11" 34 | 描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21" 35 | 描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211" 36 | 描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221" 37 | ``` 38 | 39 | 要 **描述** 一个数字字符串,首先要将字符串分割为 **最小** 数量的组,每个组都由连续的最多 **相同字符** 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。 40 | 41 | 例如,数字字符串 `"3322251"` 的描述如下图: 42 | 43 | ![](https://files.mdnice.com/user/17787/77039137-309e-43d4-8217-11023e6dd1c9.png) 44 | 45 | ## 2. 示例 46 | 47 | **示例 1** 48 | 49 | ``` 50 | 输入:n = 1 51 | 输出:"1" 52 | 解释:这是一个基本样例。 53 | ``` 54 | 55 | **示例 2** 56 | 57 | ``` 58 | 输入:n = 4 59 | 输出:"1211" 60 | 解释: 61 | countAndSay(1) = "1" 62 | countAndSay(2) = 读 "1" = 一 个 1 = "11" 63 | countAndSay(3) = 读 "11" = 二 个 1 = "21" 64 | countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211" 65 | ``` 66 | 67 | **约束条件:** 68 | 69 | - `1 <= n <= 30` 70 | 71 | ## 3. 答案 72 | 73 | ```swift 74 | class CountAndSay { 75 | func countAndSay(_ n: Int) -> String { 76 | if n == 1 { 77 | return "1" 78 | } 79 | let previousStr = countAndSay(n - 1) 80 | var currentChar = previousStr.first!, currentCount = 0, res = "" 81 | for (i, char) in previousStr.enumerated() { 82 | if char == currentChar { 83 | currentCount += 1 84 | } else { 85 | res += "\(currentCount)\(currentChar)" 86 | currentCount = 1 87 | currentChar = char 88 | } 89 | } 90 | res += "\(currentCount)\(currentChar)" 91 | return res 92 | } 93 | } 94 | ``` 95 | 96 | * 主要思想:递归获取前一个字符串,然后迭代生成当前字符串。 97 | * 时间复杂度: O(n^2) 98 | * 空间复杂度: O(1) 99 | 100 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 101 | 102 | 点击前往 [LeetCode](https://leetcode.com/problems/count-and-say/ "LeetCode") 练习 103 | 104 | ## 关于我们 105 | 106 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 107 | 108 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 109 | -------------------------------------------------------------------------------- /LeetCode/#71 简化路径.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 70 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给你一个字符串 `path` ,表示指向某一文件或目录的 Unix 风格 **绝对路径** (以 `'/'` 开头),请你将其转化为更加简洁的规范路径。 16 | 17 | 在 Unix 风格的文件系统中,一个点(`.`)表示当前目录本身;此外,两个点 (`..`) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,`'//'`)都被视为单个斜杠 `'/'` 。 对于此问题,任何其他格式的点(例如,`'...'`)均被视为文件/目录名称。 18 | 19 | 请注意,返回的 **规范路径** 必须遵循下述格式: 20 | 21 | * 始终以斜杠 `'/'` 开头。 22 | * 两个目录名之间必须只有一个斜杠 `'/'` 。 23 | * 最后一个目录名(如果存在)不能 以 `'/'` 结尾。 24 | * 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 `'.'` 或 `'..'`)。 25 | 26 | 返回简化后得到的 **规范路径** 。 27 | 28 | ## 2. 示例 29 | 30 | **示例 1** 31 | 32 | ``` 33 | 输入:path = "/home/" 34 | 输出:"/home" 35 | 解释:注意,最后一个目录名后面没有斜杠。 36 | ``` 37 | 38 | **示例 2** 39 | 40 | ``` 41 | 输入:path = "/../" 42 | 输出:"/" 43 | 解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。 44 | ``` 45 | 46 | **示例 3** 47 | 48 | ``` 49 | 输入:path = "/home//foo/" 50 | 输出:"/home/foo" 51 | 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。 52 | ``` 53 | 54 | **示例 4** 55 | 56 | ``` 57 | 输入:path = "/a/./b/../../c/" 58 | 输出:"/c" 59 | ``` 60 | 61 | **约束条件:** 62 | 63 | - `1 <= path.length <= 3000` 64 | - `path` 由英文字母,数字,`'.'`,`'/'` 或 `'_'` 组成。 65 | - `path` 是一个有效的 Unix 风格绝对路径。 66 | 67 | ## 3. 答案 68 | 69 | ```swift 70 | class SimplifyPath { 71 | func simplifyPath(_ path: String) -> String { 72 | var directories = [String]() 73 | let components = path.split(separator: "/") 74 | for component in components { 75 | switch component { 76 | case "": break // do nothing 77 | case ".": break // do nothing, pointing to the current directory 78 | case "..": 79 | directories.popLast() // if empty, does nothing 80 | default: 81 | directories.append(String(component)) 82 | } 83 | } 84 | return "/" + String(directories.joined(separator: "/")) 85 | } 86 | } 87 | ``` 88 | 89 | * 主要思想:使用堆栈,正常 push, ..流行。 90 | * 时间复杂度: O(n) 91 | * 空间复杂度: O(n) 92 | 93 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 94 | 95 | 点击前往 [LeetCode](https://leetcode.com/problems/simplify-path/ "LeetCode") 练习 96 | 97 | ## 关于我们 98 | 99 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 100 | 101 | Swift社区 102 | -------------------------------------------------------------------------------- /LeetCode/#76 最小覆盖子串(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 75 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:困难 14 | 15 | ## 1. 描述 16 | 17 | 给你一个字符串 `s` 、一个字符串 `t` 。返回 `s` 中涵盖 `t` 所有字符的最小子串。如果 `s` 中不存在涵盖 `t` 所有字符的子串,则返回空字符串 `""` 。 18 | 19 | **注意:** 20 | 21 | * 对于 `t` 中重复字符,我们寻找的子字符串中该字符数量必须不少于 `t` 中该字符数量。 22 | * 如果 `s` 中存在这样的子串,我们保证它是唯一的答案。 23 | 24 | ## 2. 示例 25 | 26 | **示例 1** 27 | 28 | ``` 29 | 输入:s = "ADOBECODEBANC", t = "ABC" 30 | 输出:"BANC" 31 | ``` 32 | 33 | **示例 2** 34 | 35 | ``` 36 | 输入:s = "a", t = "a" 37 | 输出:"a" 38 | ``` 39 | 40 | **示例 3** 41 | 42 | ``` 43 | 输入: s = "a", t = "aa" 44 | 输出: "" 45 | 解释: t 中两个字符 'a' 均应包含在 s 的子串中, 46 | 因此没有符合条件的子字符串,返回空字符串。 47 | ``` 48 | 49 | **约束条件:** 50 | 51 | - `1 <= s.length, t.length <= 10^5` 52 | - `s` 和 `t` 由英文字母组成 53 | 54 | ## 3. 答案 55 | 56 | ```swift 57 | class MinimumWindowSubsequence { 58 | func minWindow(_ S: String, _ T: String) -> String { 59 | let m = T.count, n = S.count, sChars = Array(S), tChars = Array(T) 60 | var dp = Array(repeating: Array(repeating: 0, count: n + 1), count: m + 1) 61 | var start = 0, len = n + 1 62 | 63 | for i in 0...n { 64 | dp[0][i] = i + 1 65 | } 66 | 67 | for i in 1...m { 68 | for j in 1...n { 69 | if tChars[i - 1] == sChars[j - 1] { 70 | dp[i][j] = dp[i - 1][j - 1] 71 | } else { 72 | dp[i][j] = dp[i][j - 1] 73 | } 74 | } 75 | } 76 | 77 | for i in 1...n { 78 | if dp[m][i] != 0 { 79 | if i - dp[m][i] + 1 < len { 80 | len = i - dp[m][i] + 1 81 | start = dp[m][i] - 1 82 | } 83 | } 84 | } 85 | 86 | return len == n + 1 ? "" : String(sChars[start.. 104 | -------------------------------------------------------------------------------- /LeetCode/#43 字符串相乘.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 42 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定两个以字符串形式表示的非负整数 `num1` 和 `num2`,返回 `num1` 和 `num2` 的乘积,它们的乘积也表示为字符串形式。 16 | 17 | **注意:**不能使用任何内置的 `BigInteger` 库或直接将输入转换为整数。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入: num1 = "2", num2 = "3" 25 | 输出: "6" 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入: num1 = "123", num2 = "456" 32 | 输出: "56088" 33 | ``` 34 | 35 | **约束条件:** 36 | 37 | - `1 <= num1.length, num2.length <= 200` 38 | - `num1` 和 `num2` 只能由数字组成。 39 | - `num1` 和 `num2` 都不包含任何前导零,除了数字0本身。 40 | 41 | ## 3. 答案 42 | 43 | ```swift 44 | class MultiplyStrings { 45 | func multiply(_ num1: String, _ num2: String) -> String { 46 | let num1 = num1.reversed(), num2 = num2.reversed() 47 | var res = Array(repeating: 0, count: num1.count + num2.count), resStr = "" 48 | 49 | // calculate product for every digit 50 | for (i, char1) in num1.enumerated() { 51 | 52 | guard let digit1 = Int(String(char1)) else { 53 | fatalError("Invalid Input num1") 54 | } 55 | 56 | for (j, char2) in num2.enumerated() { 57 | guard let digit2 = Int(String(char2)) else { 58 | fatalError("Invalid Input num2") 59 | } 60 | 61 | res[i + j] += digit1 * digit2 62 | } 63 | } 64 | 65 | // update digits 66 | for i in 0.. 难度水平:困难 14 | 15 | ## 1. 描述 16 | 17 | 给你两个单词 `word1` 和 `word2`, 请返回将 `word1` 转换成 `word2` 所使用的最少操作数 。 18 | 19 | 你可以对一个单词进行如下三种操作: 20 | 21 | * 插入一个字符 22 | * 删除一个字符 23 | * 替换一个字符 24 | 25 | ## 2. 示例 26 | 27 | **示例 1** 28 | 29 | ``` 30 | 输入:word1 = "horse", word2 = "ros" 31 | 输出:3 32 | 解释: 33 | horse -> rorse (将 'h' 替换为 'r') 34 | rorse -> rose (删除 'r') 35 | rose -> ros (删除 'e') 36 | ``` 37 | 38 | **示例 2** 39 | 40 | ``` 41 | 输入:word1 = "intention", word2 = "execution" 42 | 输出:5 43 | 解释: 44 | intention -> inention (删除 't') 45 | inention -> enention (将 'i' 替换为 'e') 46 | enention -> exention (将 'n' 替换为 'x') 47 | exention -> exection (将 'n' 替换为 'c') 48 | exection -> execution (插入 'u') 49 | ``` 50 | 51 | **约束条件:** 52 | 53 | - `0 <= word1.length, word2.length <= 500` 54 | - `word1` 和 `word2` 由小写英文字母组成 55 | 56 | ## 3. 答案 57 | 58 | ```swift 59 | class EditDistance { 60 | func minDistance(word1: String, _ word2: String) -> Int { 61 | let aChars = [Character](word1.characters) 62 | let bChars = [Character](word2.characters) 63 | let aLen = aChars.count 64 | let bLen = bChars.count 65 | 66 | var dp = Array(count: aLen + 1, repeatedValue:(Array(count: bLen + 1, repeatedValue: 0))) 67 | 68 | for i in 0...aLen { 69 | for j in 0...bLen { 70 | if i == 0 { 71 | dp[i][j] = j 72 | } else if j == 0 { 73 | dp[i][j] = i 74 | } else if aChars[i - 1] == bChars[j - 1] { 75 | dp[i][j] = dp[i - 1][j - 1] 76 | } else { 77 | dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1 78 | } 79 | } 80 | } 81 | 82 | return dp[aLen][bLen] 83 | } 84 | } 85 | ``` 86 | 87 | * 主要思想:2D动态编程,从插入,删除或替换一个字符中找到最小步骤。 88 | * 时间复杂度: O(mn) 89 | * 空间复杂度: O(mn) 90 | 91 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 92 | 93 | 点击前往 [LeetCode](https://leetcode.com/problems/edit-distance/ "LeetCode") 练习 94 | 95 | ## 关于我们 96 | 97 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 98 | 99 | Swift社区 100 | -------------------------------------------------------------------------------- /LeetCode/#65-有效数字.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 64 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:困难 12 | 13 | 14 | ## 1. 描述 15 | 16 | **有效数字**(按顺序)可以分成以下几个部分: 17 | 18 | 1. 一个 小数 或者 整数 19 | 2. (可选)一个 `'e'` 或 `'E'` ,后面跟着一个 整数 20 | 21 | **小数**(按顺序)可以分成以下几个部分: 22 | 23 | 1. (可选)一个符号字符(`'+'` 或 `'-'`) 24 | 2. 下述格式之一: 25 | 1. 至少一位数字,后面跟着一个点 `'.'` 26 | 2. 至少一位数字,后面跟着一个点 `'.'` ,后面再跟着至少一位数字 27 | 3. 一个点 `'.'` ,后面跟着至少一位数字 28 | 29 | **整数**(按顺序)可以分成以下几个部分: 30 | 31 | 1. (可选)一个符号字符(`'+'` 或 `'-'`) 32 | 2. 至少一位数字 33 | 34 | 部分有效数字列举如下:`["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]` 35 | 36 | 部分无效数字列举如下:`["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]` 37 | 38 | 给你一个字符串 `s` ,如果 `s` 是一个 有效数字 ,请返回 `true`。 39 | 40 | ## 2. 示例 41 | 42 | **示例 1** 43 | 44 | ``` 45 | 输入:s = "0" 46 | 输出:true 47 | ``` 48 | 49 | **示例 2** 50 | 51 | ``` 52 | 输入:s = "e" 53 | 输出:false 54 | ``` 55 | 56 | **示例 3** 57 | 58 | ``` 59 | 输入:s = "." 60 | 输出:false 61 | ``` 62 | 63 | **约束条件:** 64 | 65 | - `1 <= s.length <= 20` 66 | - `s` 仅含英文字母(大写和小写),数字(`0-9`),加号 `'+'` ,减号 `'-'` ,或者点 `'.'` 。 67 | 68 | ## 3. 答案 69 | 70 | ```swift 71 | class MinimumPathSum { 72 | func minPathSum(_ grid: [[Int]]) -> Int { 73 | guard grid.count != 0 && grid[0].count != 0 else{ 74 | return 0 75 | } 76 | 77 | let m = grid.count, n = grid[0].count 78 | var dp = Array(repeating: Array(repeating: 0, count: n), count: m) 79 | 80 | for i in 0.. 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 整数数组 `nums` 按升序排列,数组中的值 **互不相同** 。 18 | 19 | 在传递给函数之前,`nums` 在预先未知的某个下标 `k`(`0 <= k < nums.length`)上进行了 **旋转**,使数组变为 `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]`(下标 **从 0 开始** 计数)。例如, `[0,1,2,4,5,6,7]` 在下标 `3` 处经旋转后可能变为 `[4,5,6,7,0,1,2]` 。 20 | 21 | 给你 旋转后 的数组 `nums` 和一个整数 `target` ,如果 `nums` 中存在这个目标值 `target` ,则返回它的下标,否则返回 `-1` 。 22 | 23 | ## 2. 示例 24 | 25 | **示例 1** 26 | 27 | ``` 28 | 输入:nums = [4,5,6,7,0,1,2], target = 0 29 | 输出:4 30 | ``` 31 | 32 | **示例 2** 33 | 34 | ``` 35 | 输入:nums = [4,5,6,7,0,1,2], target = 3 36 | 输出:-1 37 | ``` 38 | 39 | **示例 3** 40 | 41 | ``` 42 | 输入:nums = [1], target = 0 43 | 输出:-1 44 | ``` 45 | 46 | **约束条件:** 47 | 48 | - `1 <= nums.length <= 5000` 49 | - `-10^4 <= nums[i] <= 10^4` 50 | - `nums` 中的每个值都 **独一无二** 51 | - 题目数据保证 `nums` 在预先未知的某个下标上进行了旋转 52 | - `-10^4 <= target <= 10^4` 53 | 54 | > **进阶:**你可以设计一个时间复杂度为 `O(log n)` 的解决方案吗? 55 | 56 | ## 3. 答案 57 | 58 | ```swift 59 | class SearchInRotatedSortedArray { 60 | func search(nums: [Int], _ target: Int) -> Int { 61 | var left = 0 62 | var right = nums.count - 1 63 | var mid = 0 64 | 65 | while left <= right { 66 | mid = (right - left) / 2 + left 67 | 68 | if nums[mid] == target { 69 | return mid 70 | } 71 | 72 | if nums[mid] >= nums[left] { 73 | if nums[mid] > target && target >= nums[left] { 74 | right = mid - 1 75 | } else { 76 | left = mid + 1 77 | } 78 | } else { 79 | if nums[mid] < target && target <= nums[right] { 80 | left = mid + 1 81 | } else { 82 | right = mid - 1 83 | } 84 | } 85 | } 86 | 87 | return -1 88 | } 89 | } 90 | ``` 91 | 92 | * 主要思想:二叉搜索,检查左或右是否排序,然后在部分中搜索。 93 | * 时间复杂度: O(logn) 94 | * 空间复杂度: O(1) 95 | 96 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 97 | 98 | 点击前往 [LeetCode](https://leetcode.com/problems/search-in-rotated-sorted-array/ "LeetCode") 练习 99 | 100 | ## 关于我们 101 | 102 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 103 | 104 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 105 | -------------------------------------------------------------------------------- /LeetCode/#14 最长公共前缀.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 13 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:简单 10 | 11 | ## 1. 描述 12 | 13 | 编写一个函数来查找字符串数组中的最长公共前缀。 14 | 15 | 如果不存在公共前缀,返回空字符串 `""`。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:strs = ["flower","flow","flight"] 23 | 输出:"fl" 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入:strs = ["dog","racecar","car"] 30 | 输出:"" 31 | 解释:输入不存在公共前缀。 32 | ``` 33 | 34 | **约束条件:** 35 | 36 | - `1 <= strs.length <= 200` 37 | - `0 <= strs[i].length <= 200` 38 | - `strs[i]` 仅由小写英文字母组成 39 | 40 | ## 3. 答案 41 | 42 | ```swift 43 | class LongestCommonPrefix { 44 | func longestCommonPrefix(_ strs: [String]) -> String { 45 | guard let firstStr = strs.first else { 46 | return "" 47 | } 48 | 49 | var res = "" 50 | 51 | for (i, char) in firstStr.enumerated() { 52 | // dropFirst(_ k: Int = 1) returns a Substring struct 53 | for str in strs.dropFirst() { 54 | if i == str.count { 55 | return res 56 | } 57 | 58 | // Another easy way: Array(str)[i], time complexity is linear though 59 | let currentStrChar = str[str.index(str.startIndex, offsetBy: i)] 60 | 61 | if char != currentStrChar { 62 | return res 63 | } 64 | } 65 | res.append(char) 66 | } 67 | 68 | return res 69 | } 70 | } 71 | ``` 72 | 73 | * 主要思想:首先使用第一个字符串作为结果,在迭代数组时修改 74 | * 时间复杂度: O(nm) 75 | * 空间复杂度: O(m) 76 | 77 | > `m` 为最长前缀长度 78 | 79 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 80 | 81 | 点击前往 [LeetCode](https://leetcode.com/problems/longest-common-prefix/ "LeetCode") 练习 82 | 83 | ## 关于我们 84 | 85 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 86 | 87 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 88 | 89 | Swift社区 90 | 91 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 92 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 93 | 94 | -------------------------------------------------------------------------------- /LeetCode/#6 字符串“之”字形转换 .md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 已知一个字符串 `“PAYPALISHIRING”` 在确定的行数上以 “之” 字形图案书写,如下所示: 14 | 15 | ``` 16 | P A H N 17 | A P L S I I G 18 | Y I R 19 | ``` 20 | 21 | 然后逐行阅读获得一个新的字符串:`“PAHNAPLSIIGYIR”` 22 | 23 | ```Swift 24 | func convert(s: String, _ numRows: Int) -> String 25 | ``` 26 | 27 | 已知一个字符串和行数,在上述方法内编写转换的代码。 28 | 29 | 30 | ## 2. 示例 31 | 32 | **示例 1** 33 | 34 | ``` 35 | 输入: s = "PAYPALISHIRING", numRows = 3 36 | 输出: "PAHNAPLSIIGYIR" 37 | 解释: 38 | P A H N 39 | A P L S I I G 40 | Y I R 41 | ``` 42 | 43 | **示例 2** 44 | 45 | ``` 46 | 输入: s = "PAYPALISHIRING", numRows = 4 47 | 输出: "PINALSIGYAHRPI" 48 | 解释: 49 | P I N 50 | A L S I G 51 | Y A H R 52 | P I 53 | ``` 54 | 55 | **示例 3** 56 | 57 | ``` 58 | 输入: s = "A", numRows = 1 59 | 输出: "A" 60 | ``` 61 | 62 | 约束条件: 63 | - `1 <= s.length <= 1000` 64 | - `s` 英文字母 `,` 和 `.`组成。 65 | - `1 <= numRows <= 1000` 66 | 67 | ## 3. 答案 68 | 69 | ```swift 70 | class Solution { 71 | func convert(s: String, _ numRows: Int) -> String { 72 | if numRows == 1 { 73 | return s 74 | } 75 | 76 | var ret: [Character] = [] 77 | var chars: [Character] = [Character](s.characters) 78 | let cnt = chars.count 79 | 80 | for i in 0.. 115 | -------------------------------------------------------------------------------- /LeetCode/#54 螺旋矩阵.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 53 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 给你一个 `m` 行 `n` 列的矩阵 `matrix` ,请按照 **顺时针螺旋顺序** ,返回矩阵中的所有元素。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 23 | 输出:[1,2,3,6,9,8,7,4,5] 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 30 | 输出:[1,2,3,4,8,12,11,10,9,5,6,7] 31 | ``` 32 | 33 | **约束条件:** 34 | 35 | - `m == matrix.length` 36 | - `n == matrix[i].length` 37 | - `1 <= m, n <= 10` 38 | - `-100 <= matrix[i][j] <= 100` 39 | 40 | ## 3. 答案 41 | 42 | ```swift 43 | class SpiralMatrix { 44 | func spiralOrder(_ matrix: [[Int]]) -> [Int] { 45 | var res = [Int]() 46 | 47 | guard matrix.count != 0 else { 48 | return res 49 | } 50 | 51 | var startX = 0 52 | var endX = matrix.count - 1 53 | var startY = 0 54 | var endY = matrix[0].count - 1 55 | 56 | while true { 57 | // top 58 | for i in startY...endY { 59 | res.append(matrix[startX][I]) 60 | } 61 | startX += 1 62 | if startX > endX { 63 | break 64 | } 65 | 66 | // right 67 | for i in startX...endX { 68 | res.append(matrix[i][endY]) 69 | } 70 | endY -= 1 71 | if startY > endY { 72 | break 73 | } 74 | 75 | // bottom 76 | for i in stride(from: endY, through: startY, by: -1) { 77 | res.append(matrix[endX][I]) 78 | } 79 | endX -= 1 80 | if startX > endX { 81 | break 82 | } 83 | 84 | // left 85 | for i in stride(from: endX, through: startX, by: -1) { 86 | res.append(matrix[i][startY]) 87 | } 88 | startY += 1 89 | if startY > endY { 90 | break 91 | } 92 | } 93 | 94 | return res 95 | } 96 | } 97 | ``` 98 | 99 | * 主要思想:在迭代过程中使用四个索引来获得正确的元素。 100 | * 时间复杂度: O(n^2) 101 | * 空间复杂度: O(1) 102 | 103 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 104 | 105 | 点击前往 [LeetCode](https://leetcode.com/problems/spiral-matrix/ "LeetCode") 练习 106 | 107 | ## 关于我们 108 | 109 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 110 | 111 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 112 | -------------------------------------------------------------------------------- /LeetCode/#34 在排序数组中查找元素的第一个和最后一个位置(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 33 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给定一个按照升序排列的整数数组 `nums`,和一个目标值 `target`。找出给定目标值在数组中的开始位置和结束位置。 18 | 19 | 如果数组中不存在目标值 `target`,返回 `[-1, -1]`。 20 | 21 | **进阶:** 22 | 23 | * 你可以设计并实现时间复杂度为 `O(log n)` 的算法解决此问题吗? 24 | 25 | ## 2. 示例 26 | 27 | **示例 1** 28 | 29 | ``` 30 | 输入:nums = [5,7,7,8,8,10], target = 8 31 | 输出:[3,4] 32 | ``` 33 | 34 | **示例 2** 35 | 36 | ``` 37 | 输入:nums = [5,7,7,8,8,10], target = 6 38 | 输出:[-1,-1] 39 | ``` 40 | 41 | **示例 3** 42 | 43 | ``` 44 | 输入:nums = [], target = 0 45 | 输出:[-1,-1] 46 | ``` 47 | 48 | **约束条件:** 49 | 50 | - `0 <= nums.length <= 10^5` 51 | - -10^9 <= nums[i] <= 10^9 52 | - `nums` 是一个非递减数组 53 | - `-10^9 <= target <= 10^9` 54 | 55 | ## 3. 答案 56 | 57 | ```swift 58 | class SearchForARange { 59 | func searchRange(_ nums: [Int], _ target: Int) -> [Int] { 60 | guard !nums.isEmpty else { 61 | return [-1, -1] 62 | } 63 | 64 | return [searchStartIdx(nums, target), searchEndIdx(nums, target)] 65 | } 66 | 67 | private func searchStartIdx(_ nums: [Int], _ target: Int) -> Int { 68 | var left = 0, right = nums.count - 1 69 | 70 | while left + 1 < right { 71 | let mid = (right - left) / 2 + left 72 | 73 | if nums[mid] < target { 74 | left = mid + 1 75 | } else { 76 | right = mid 77 | } 78 | } 79 | 80 | return nums[left] == target ? left : nums[right] == target ? right : -1 81 | } 82 | 83 | private func searchEndIdx(_ nums: [Int], _ target: Int) -> Int { 84 | var left = 0, right = nums.count - 1 85 | 86 | while left + 1 < right { 87 | let mid = (right - left) / 2 + left 88 | 89 | if nums[mid] > target { 90 | right = mid - 1 91 | } else { 92 | left = mid 93 | } 94 | } 95 | 96 | return nums[right] == target ? right : nums[left] == target ? left : -1 97 | } 98 | } 99 | ``` 100 | 101 | * 主要思想:二分搜索,分别检查左边或右边。 102 | * 时间复杂度: O(logn) 103 | * 空间复杂度: O(1) 104 | 105 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 106 | 107 | 点击前往 [LeetCode](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ "LeetCode") 练习 108 | 109 | ## 关于我们 110 | 111 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 112 | 113 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 -------------------------------------------------------------------------------- /LeetCode/#73 矩阵置零.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 72 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给定一个 `m x n` 的矩阵,如果一个元素为 `0` ,则将其所在行和列的所有元素都设为 `0` 。请使用 **原地** 算法。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ![](https://images.xiaozhuanlan.com/photo/2022/75e47e2b4f10b8996e790a45330093a7.png) 22 | 23 | ``` 24 | 输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] 25 | 输出:[[1,0,1],[0,0,0],[1,0,1]] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ![](https://images.xiaozhuanlan.com/photo/2022/f82ec2407d00d8f53e61dff637d9c711.png) 31 | 32 | ``` 33 | 输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]] 34 | 输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]] 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `m == matrix.length` 40 | - `n == matrix[0].length` 41 | - `1 <= m, n <= 200` 42 | - -2^31 <= matrix[i][j] <= 2^31 - 1` 43 | 44 | ## 3. 答案 45 | 46 | ```swift 47 | class SetMatrixZeroes { 48 | func setZeroes(_ matrix: inout [[Int]]) { 49 | var rowHasZero = false, colHasZero = false 50 | let m = matrix.count, n = matrix[0].count 51 | 52 | for i in 0.. 107 | -------------------------------------------------------------------------------- /LeetCode/#31 下一个排列 (Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 29 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 整数数组的一个 **排列** 就是将其所有成员以序列或线性顺序排列。 18 | 19 | 例如,`arr = [1,2,3]`,以下这些都可以视作 `arr` 的排列:`[1,2,3]`、`[1,3,2]`、`[3,1,2]`、`[2,3,1]`。 20 | 21 | 整数数组的 **下一个排列** 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 **下一个排列** 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。 22 | 23 | * 例如,`arr = [1,2,3]` 的下一个排列是 `[1,3,2]`。 24 | * 类似地,`arr = [2,3,1]` 的下一个排列是 `[3,1,2]`。 25 | * 而 `arr = [3,2,1]` 的下一个排列是 `[1,2,3]`,因为 `[3,2,1]` 不存在一个字典序更大的排列。 26 | 27 | 给你一个整数数组 `nums` ,找出 `nums` 的下一个排列。 28 | 29 | 必须 **原地** 修改,只允许使用额外常数空间。 30 | 31 | ## 2. 示例 32 | 33 | **示例 1** 34 | 35 | ``` 36 | 输入:nums = [1,2,3] 37 | 输出:[1,3,2] 38 | ``` 39 | 40 | **示例 2** 41 | 42 | ``` 43 | 输入:nums = [3,2,1] 44 | 输出:[1,2,3] 45 | ``` 46 | 47 | **示例 3** 48 | 49 | ``` 50 | 输入:nums = [1,1,5] 51 | 输出:[1,5,1] 52 | ``` 53 | 54 | **约束条件:** 55 | 56 | - `1 <= nums.length <= 100` 57 | - `0 <= nums[i] <= 100` 58 | 59 | ## 3. 答案 60 | 61 | ```swift 62 | class NextPermutation { 63 | func nextPermutation(_ nums: inout [Int]) { 64 | guard let violateIndex = findViolate(nums) else { 65 | nums.reverse() 66 | return 67 | } 68 | 69 | swap(&nums, violateIndex, findLeastGreater(nums, violateIndex)) 70 | nums = nums[0...violateIndex] + nums[(violateIndex + 1)...].reversed() 71 | } 72 | 73 | fileprivate func findViolate(_ nums: [Int]) -> Int? { 74 | for i in (1.. nums[i - 1] { 76 | return i - 1 77 | } 78 | } 79 | 80 | return nil 81 | } 82 | 83 | fileprivate func findLeastGreater(_ nums: [Int], _ violateIndex: Int) -> Int { 84 | for i in (violateIndex + 1.. nums[violateIndex] { 86 | return i 87 | } 88 | } 89 | 90 | fatalError() 91 | } 92 | 93 | fileprivate func swap(_ nums: inout [T], _ indexL: Int, _ indexR: Int) { 94 | (nums[indexL], nums[indexR]) = (nums[indexR], nums[indexL]) 95 | } 96 | } 97 | ``` 98 | 99 | * 主要思想:从右到左遍历数字,将第一个较小的数字替换为最小的更大的数字,然后反转所有数字。 100 | * 时间复杂度: O(n) 101 | * 空间复杂度: O(1) 102 | 103 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 104 | 105 | 点击前往 [LeetCode](https://leetcode.com/problems/next-permutation/ "LeetCode") 练习 106 | 107 | ## 关于我们 108 | 109 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 110 | 111 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 112 | -------------------------------------------------------------------------------- /LeetCode/#81 搜索旋转排序数组 II.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 80 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 已知存在一个按非降序排列的整数数组 `nums` ,数组中的值不必互不相同。 16 | 17 | 在传递给函数之前,`nums` 在预先未知的某个下标 `k`(`0 <= k < nums.length`)上进行了 **旋转** ,使数组变为 `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]`(下标 **从 0 开始** 计数)。例如, `[0,1,2,4,4,4,5,6,6,7]` 在下标 `5` 处经旋转后可能变为 `[4,5,6,6,7,0,1,2,4,4]` 。 18 | 19 | 给你 **旋转后** 的数组 `nums` 和一个整数 `target` ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 `nums` 中存在这个目标值 `target` ,则返回 `true` ,否则返回 `false` 。 20 | 21 | 你必须尽可能减少整个操作步骤。 22 | 23 | ## 2. 示例 24 | 25 | **示例 1** 26 | 27 | ``` 28 | 输入:nums = [2,5,6,0,0,1,2], target = 0 29 | 输出:true 30 | ``` 31 | 32 | **示例 2** 33 | 34 | ``` 35 | 输入:nums = [2,5,6,0,0,1,2], target = 3 36 | 输出:false 37 | ``` 38 | 39 | **约束条件:** 40 | 41 | - `1 <= nums.length <= 5000` 42 | - `-10^4 <= nums[i] <= 10^4` 43 | - 题目数据保证 `nums` 在预先未知的某个下标上进行了旋转 44 | - `-10^4 <= target <= 10^4` 45 | 46 | **进阶:** 47 | 48 | * 这是 `搜索旋转排序数组` 的延伸题目,本题中的 `nums` 可能包含重复元素。 49 | * 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么? 50 | 51 | ## 3. 答案 52 | 53 | ```swift 54 | class SearchInRotatedSortedArrayII { 55 | func search(nums: [Int], _ target: Int) -> Bool { 56 | var left = 0 57 | var right = nums.count - 1 58 | var mid = 0 59 | 60 | while left <= right { 61 | mid = (right - left) / 2 + left 62 | 63 | if nums[mid] == target { 64 | return true 65 | } 66 | 67 | if nums[mid] > nums[left] { 68 | if nums[mid] > target && target >= nums[left] { 69 | right = mid - 1 70 | } else { 71 | left = mid + 1 72 | } 73 | } else if nums[mid] < nums[left]{ 74 | if nums[mid] < target && target <= nums[right] { 75 | left = mid + 1 76 | } else { 77 | right = mid - 1 78 | } 79 | } else { 80 | left += 1 81 | } 82 | } 83 | 84 | return false 85 | } 86 | } 87 | ``` 88 | 89 | * 主要思想:二分查找,检查左或右是否排序,然后在部分中查找,如果重复则跳转。 90 | * 时间复杂度: O(logn) 91 | * 空间复杂度: O(1) 92 | 93 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 94 | 95 | 点击前往 [LeetCode](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ "LeetCode") 练习 96 | 97 | ## 关于我们 98 | 99 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 100 | 101 | Swift社区 102 | -------------------------------------------------------------------------------- /LeetCode/#10 正则表达式匹配.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:困难 10 | 11 | ## 1. 描述 12 | 给定输入字符串 `s` 和模式 `p`,实现支持 `'.'` 的正则表达式匹配 和 `'*'` ,其中: 13 | - `'.'` 匹配任何单个字符。 14 | - `'*'` 匹配零个或多个前面的元素。 15 | 匹配应该覆盖**整个**输入字符串(不是部分)。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入: s = "aa", p = "a" 23 | 输出: 假 24 | 说明: “a” 与整个字符串 “aa” 不匹配。 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入: s = "aa", p = "a*" 31 | 输出: 真 32 | 说明: '*' 表示前面的元素 'a' 中的零个或多个。 因此,通过重复 'a' 一次,它就变成了 “aa”。 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入: s = "ab", p = ".*" 39 | 输出: 真 40 | 说明: “.*” 表示“零个或多个 (*) 的任何字符 (.)”。 41 | ``` 42 | 43 | **示例 4** 44 | 45 | ``` 46 | 输入: s = "aab", p = "c*a*b" 47 | 输出: 真 48 | 说明: c 可以重复 0 次,a 可以重复 1 次。 因此,它匹配 “aab”。 49 | 50 | ``` 51 | 52 | **示例 5** 53 | 54 | ``` 55 | 输入: s = "mississippi", p = "mis*is*p*." 56 | 输出: 假 57 | ``` 58 | 59 | **约束条件:** 60 | - `1 <= s.length <= 20` 61 | - `1 <= p.length <= 30` 62 | - `s` 仅包含小写英文字母。 63 | - `p` 仅包含小写英文字母 `“.”` 和 `“*”`。 64 | - 保证每次出现字符 `“*”` 时,都会有一个前一个有效字符进行匹配。 65 | 66 | ## 3. 答案 67 | 68 | ```swift 69 | class RegularExpressionMatching { 70 | func isMatch(_ s: String, _ p: String) -> Bool { 71 | let sChars = Array(s), pChars = Array(p) 72 | var dp = Array(repeating: Array(repeating: false, count: pChars.count + 1), count: sChars.count + 1) 73 | dp[0][0] = true 74 | 75 | for i in 0...pChars.count { 76 | // jump over "" vs. "x*" case 77 | dp[0][i] = i == 0 || i > 1 && dp[0][i - 2] && pChars[i - 1] == "*" 78 | } 79 | 80 | for i in 0...sChars.count { 81 | for j in 0...pChars.count { 82 | guard j > 0 else { 83 | continue 84 | } 85 | 86 | let pCurrent = pChars[j - 1] 87 | 88 | if pCurrent != "*" { 89 | dp[i][j] = i > 0 && dp[i - 1][j - 1] && (pCurrent == "." || pCurrent == sChars[i - 1]) 90 | } else { 91 | dp[i][j] = dp[i][j - 2] || i > 0 && j > 1 && (sChars[i - 1] == pChars[j - 2] || pChars[j - 2] == ".") && dp[i - 1][j] 92 | } 93 | } 94 | } 95 | 96 | return dp[sChars.count][pChars.count] 97 | } 98 | } 99 | ``` 100 | 101 | * 主要思想:经典二维动态规划。 102 | * 时间复杂度: O(m*n) 103 | * 空间复杂度: O(m*n) 104 | 105 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 106 | 107 | 点击前往 [LeetCode](https://leetcode.com/problems/regular-expression-matching/ "LeetCode") 练习 108 | 109 | ## 关于我们 110 | 111 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 112 | 113 | Swift社区 114 | -------------------------------------------------------------------------------- /LeetCode/#21 合并两个有序链表(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 20 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:简单 12 | 13 | ## 1. 描述 14 | 15 | 将两个升序链表合并为一个新的 **升序** 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ![](https://assets.leetcode.com/uploads/2020/10/03/merge_ex1.jpg) 22 | 23 | ``` 24 | 输入:l1 = [1,2,4], l2 = [1,3,4] 25 | 输出:[1,1,2,3,4,4] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:l1 = [], l2 = [] 32 | 输出:[] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:l1 = [], l2 = [0] 39 | 输出:[0] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - 两个链表的节点数目范围是 `[0, 50]` 45 | - `-100 <= Node.val <= 100` 46 | - `l1` 和 `l2` 均按 **非递减顺序** 排列 47 | 48 | ## 3. 答案 49 | 50 | ```swift 51 | /** 52 | * Definition for singly-linked list. 53 | * public class ListNode { 54 | * public var val: Int 55 | * public var next: ListNode? 56 | * public init(_ val: Int) { 57 | * self.val = val 58 | * self.next = nil 59 | * } 60 | * } 61 | */ 62 | 63 | class MergeTwoSortedLists { 64 | func mergeTwoLists(l1: ListNode?, _ l2: ListNode?) -> ListNode? { 65 | let dummy = ListNode(0) 66 | var node = dummy 67 | 68 | var l1 = l1 69 | var l2 = l2 70 | 71 | while l1 != nil && l2 != nil { 72 | if l1!.val < l2!.val { 73 | node.next = l1 74 | l1 = l1!.next 75 | } else { 76 | node.next = l2 77 | l2 = l2!.next 78 | } 79 | node = node.next! 80 | } 81 | 82 | node.next = l1 ?? l2 83 | 84 | return dummy.next 85 | } 86 | } 87 | ``` 88 | 89 | * 主要思想:Dummy Node来遍历两个列表,比较两个节点并指向右边的一个。 90 | * 时间复杂度: O(n) 91 | * 空间复杂度: O(1) 92 | 93 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 94 | 95 | 点击前往 [LeetCode](https://leetcode.com/problems/merge-two-sorted-lists/ "LeetCode") 练习 96 | 97 | 98 | ## 关于我们 99 | 100 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 101 | 102 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 103 | 104 | Swift社区 105 | 106 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 107 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 108 | 109 | 110 | -------------------------------------------------------------------------------- /LeetCode/#74 搜索二维矩阵.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 73 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 编写一个高效的算法来判断 `m x n` 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 16 | 17 | * 每行中的整数从左到右按升序排列。 18 | * 每行的第一个整数大于前一行的最后一个整数。 19 | 20 | ## 2. 示例 21 | 22 | **示例 1** 23 | 24 | ![](https://images.xiaozhuanlan.com/photo/2022/06c35690518617675c110e41424111a0.png) 25 | 26 | ``` 27 | 输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 28 | 输出:true 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ![](https://images.xiaozhuanlan.com/photo/2022/b2d0c81496e82f7135f7b27cb45e0ca6.png) 34 | 35 | ``` 36 | 输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 37 | 输出:false 38 | ``` 39 | 40 | **约束条件:** 41 | 42 | - `m == matrix.length` 43 | - `n == matrix[i].length` 44 | - `1 <= m, n <= 100` 45 | - `-10^4 <= matrix[i][j], target <= 10^4` 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class Search2DMatrix { 51 | func searchMatrix(_ matrix: [[Int]], _ target: Int) -> Bool { 52 | if matrix.count == 0 || matrix[0].count == 0 { 53 | return false 54 | } 55 | 56 | let rowNum = searchRow(matrix, target) 57 | return searchCol(matrix[rowNum], target) 58 | } 59 | 60 | private func searchRow(_ matrix: [[Int]], _ target: Int) -> Int { 61 | var left = 0, right = matrix.count - 1 62 | 63 | while left + 1 < right { 64 | let mid = (right - left) / 2 + left 65 | if matrix[mid][0] == target { 66 | return mid 67 | } else if matrix[mid][0] < target { 68 | left = mid 69 | } else { 70 | right = mid 71 | } 72 | } 73 | 74 | return matrix[right][0] <= target ? right : left 75 | } 76 | 77 | private func searchCol(_ nums: [Int], _ target: Int) -> Bool { 78 | var left = 0, right = nums.count - 1 79 | 80 | while left <= right { 81 | let mid = (right - left) / 2 + left 82 | if nums[mid] == target { 83 | return true 84 | } else if nums[mid] < target { 85 | left = mid + 1 86 | } else { 87 | right = mid - 1 88 | } 89 | } 90 | 91 | return false 92 | } 93 | } 94 | ``` 95 | 96 | * 主要思想:搜索col,然后二分查找row。 97 | * 时间复杂度: O(log(m + n)) 98 | * 空间复杂度: O(1) 99 | 100 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 101 | 102 | 点击前往 [LeetCode](https://leetcode.com/problems/search-a-2d-matrix/ "LeetCode") 练习 103 | 104 | ## 关于我们 105 | 106 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 107 | 108 | Swift社区 109 | -------------------------------------------------------------------------------- /LeetCode/#57 插入区间.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 56 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给你一个 **无重叠的** ,按照区间起始端点排序的区间列表。 14 | 15 | 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 16 | 17 | ## 2. 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:intervals = [[1,3],[6,9]], newInterval = [2,5] 23 | 输出:[[1,5],[6,9]] 24 | ``` 25 | 26 | **示例 2** 27 | 28 | ``` 29 | 输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] 30 | 输出:[[1,2],[3,10],[12,16]] 31 | 解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。 32 | ``` 33 | 34 | **示例 3** 35 | 36 | ``` 37 | 输入:intervals = [], newInterval = [5,7] 38 | 输出:[[5,7]] 39 | ``` 40 | 41 | **示例 4** 42 | 43 | ``` 44 | 输入:intervals = [[1,5]], newInterval = [2,3] 45 | 输出:[[1,5]] 46 | ``` 47 | 48 | **示例 5** 49 | 50 | ``` 51 | 输入:intervals = [[1,5]], newInterval = [2,7] 52 | 输出:[[1,7]] 53 | ``` 54 | 55 | **约束条件:** 56 | 57 | - `0 <= intervals.length <= 10^4` 58 | - `intervals[i].length == 2` 59 | - `0 <= intervals[i][0] <= intervals[i][1] <= 10^5` 60 | - `intervals` 根据 `intervals[i][0]` 按 **升序** 排列 61 | - `newInterval.length == 2` 62 | - `0 <= newInterval[0] <= newInterval[1] <= 10^5` 63 | 64 | ## 3. 答案 65 | 66 | ```swift 67 | /** 68 | * Definition for an interval. 69 | * public class Interval { 70 | * public var start: Int 71 | * public var end: Int 72 | * public init(_ start: Int, _ end: Int) { 73 | * self.start = start 74 | * self.end = end 75 | * } 76 | * } 77 | */ 78 | class InsertInterval { 79 | func insert(_ intervals: [Interval], _ newInterval: Interval) -> [Interval] { 80 | var index = 0 81 | var result: [Interval] = [] 82 | var tempInterval = Interval(newInterval.start, newInterval.end) 83 | 84 | while index < intervals.count && newInterval.start > intervals[index].end { 85 | result.append(intervals[index]) 86 | index += 1 87 | } 88 | 89 | while index < intervals.count && newInterval.end >= intervals[index].start { 90 | let minStart = min(tempInterval.start, intervals[index].start) 91 | let maxEnd = max(tempInterval.end, intervals[index].end) 92 | tempInterval = Interval(minStart, maxEnd) 93 | index += 1 94 | } 95 | result.append(tempInterval) 96 | 97 | for i in index ..< intervals.count { 98 | result.append(intervals[i]) 99 | } 100 | 101 | return result 102 | } 103 | } 104 | ``` 105 | 106 | * 主要思想:首先,检查nuewInterval的开始是否大于一个interval的结束。如果是,保存索引,否则保存间隔;第二,如果nuewInterval的end大于一个interval的start,则继续更新一个新的interval。如果不能找到更多的interval,则将新的interval附加到结果数组中;最后一步,将剩余间隔添加到结果数组 107 | * 时间复杂度: O(n) 108 | * 空间复杂度: O(1) 109 | 110 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 111 | 112 | 点击前往 [LeetCode](https://leetcode.com/problems/insert-interval/ "LeetCode") 练习 113 | 114 | ## 关于我们 115 | 116 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 117 | 118 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 119 | -------------------------------------------------------------------------------- /LeetCode/#44 通配符匹配.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 43 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | 给定一个字符串 (`s`) 和一个字符模式 (`p`) ,实现一个支持 `'?'` 和 `'*'` 的通配符匹配。 16 | 17 | > '?' 可以匹配任何单个字符。 18 | > 19 | > '*' 可以匹配任意字符串(包括空字符串)。 20 | 21 | 两个字符串**完全匹配**才算匹配成功。 22 | 23 | **说明:** 24 | 25 | * `s` 可能为空,且只包含从 `a-z` 的小写字母。 26 | * `p` 可能为空,且只包含从 `a-z` 的小写字母,以及字符 `?` 和 `*`。 27 | 28 | ## 2. 示例 29 | 30 | **示例 1** 31 | 32 | ``` 33 | 输入: 34 | s = "aa" 35 | p = "a" 36 | 输出: false 37 | 解释: "a" 无法匹配 "aa" 整个字符串。 38 | ``` 39 | 40 | **示例 2** 41 | 42 | ``` 43 | 输入: 44 | s = "aa" 45 | p = "*" 46 | 输出: true 47 | 解释: '*' 可以匹配任意字符串。 48 | ``` 49 | 50 | **示例 3** 51 | 52 | ``` 53 | 输入: 54 | s = "cb" 55 | p = "?a" 56 | 输出: false 57 | 解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。 58 | ``` 59 | 60 | **示例 4** 61 | 62 | ``` 63 | 输入: 64 | s = "adceb" 65 | p = "*a*b" 66 | 输出: true 67 | 解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce". 68 | ``` 69 | 70 | **示例 5** 71 | 72 | ``` 73 | 输入: 74 | s = "acdcb" 75 | p = "a*c?b" 76 | 输出: false 77 | ``` 78 | 79 | ## 3. 答案 80 | 81 | ```swift 82 | class WildcardMatching { 83 | func isMatch(_ s: String, _ p: String) -> Bool { 84 | let sChars = Array(s), pChars = Array(p) 85 | var dp = Array(repeating: Array(repeating: false, count: p.count + 1), count: s.count + 1) 86 | dp[0][0] = true 87 | 88 | // must start from 0, to make range feasible and handle empty vs. * case 89 | for i in 0...s.count { 90 | for j in 0...p.count { 91 | guard j > 0 else { 92 | continue 93 | } 94 | 95 | let pCurrent = pChars[j - 1] 96 | 97 | if pCurrent != "*" { 98 | dp[i][j] = i > 0 && dp[i - 1][j - 1] && (pCurrent == sChars[i - 1] || pCurrent == "?") 99 | } else { 100 | // Two situations: 101 | // (1) '*' is the first character in p; 102 | // (2) For k>=0 and k<=i, there is some dp[k][j-1] being true; 103 | // and '*' will match the rest sequence in s after index k; 104 | var flag = false 105 | for k in 0...i { 106 | if dp[k][j - 1] { 107 | flag = true 108 | break 109 | } 110 | } 111 | 112 | dp[i][j] = flag || j == 1 113 | } 114 | } 115 | } 116 | 117 | return dp[s.count][p.count] 118 | } 119 | } 120 | ``` 121 | 122 | * 主要思想:经典的二维动态规划。 123 | * 时间复杂度: O(mn) 124 | * 空间复杂度: O(mn) 125 | 126 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 127 | 128 | 点击前往 [LeetCode](https://leetcode.com/problems/wildcard-matching/ "LeetCode") 练习 129 | 130 | ## 关于我们 131 | 132 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 133 | 134 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 135 | -------------------------------------------------------------------------------- /LeetCode/#15 三数之和(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 14 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:中等 12 | 13 | ## 1. 描述 14 | 15 | 给你一个包含 `n` 个整数的数组 `nums`,判断 `nums` 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 `0` 且不重复的三元组。 16 | 17 | **注意:** 答案中不可以包含重复的三元组。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:nums = [-1,0,1,2,-1,-4] 25 | 输出:[[-1,-1,2],[-1,0,1]] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:nums = [] 32 | 输出:[] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:nums = [0] 39 | 输出:[] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - `0 <= nums.length <= 3000` 45 | - `-10^5 <= nums[i] <= 10^5` 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class ThreeSum { 51 | func threeSum(_ nums: [Int]) -> [[Int]] { 52 | var res = [[Int]]() 53 | 54 | guard nums.count >= 3 else { 55 | return res 56 | } 57 | 58 | let nums = nums.sorted() 59 | 60 | for i in 0.. 0 && nums[i] == nums[i - 1] { 62 | continue 63 | } 64 | 65 | let firstNum = nums[i], remainingSum = -firstNum 66 | var m = i + 1, n = nums.count - 1 67 | 68 | while m < n { 69 | if nums[m] + nums[n] == remainingSum { 70 | res.append([firstNum, nums[m], nums[n]]) 71 | 72 | repeat { 73 | m += 1 74 | } while nums[m] == nums[m - 1] && m < n 75 | 76 | repeat { 77 | n -= 1 78 | } while nums[n] == nums[n + 1] && m < n 79 | } else if nums[m] + nums[n] < remainingSum { 80 | m += 1 81 | } else { 82 | n -= 1 83 | } 84 | } 85 | } 86 | 87 | return res 88 | } 89 | } 90 | ``` 91 | 92 | * 主要思想:对数组进行排序并遍历,根据它们的和大于或不大于目标,向左递增或向右递减 93 | * 时间复杂度: O(n^2) 94 | * 空间复杂度: O(nC3) 95 | 96 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 97 | 98 | 点击前往 [LeetCode](https://leetcode.com/problems/3sum "LeetCode") 练习 99 | 100 | ## 关于我们 101 | 102 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 103 | 104 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 105 | 106 | Swift社区 107 | 108 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 109 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 110 | 111 | -------------------------------------------------------------------------------- /LeetCode/#16 最接近的三数之和.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 15 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给你一个长度为 `n` 的整数数组 `nums` 和 一个目标值 `target`。请你从 `nums` 中选出三个整数,使它们的和与 `target` 最接近。 14 | 15 | 返回这三个数的和。 16 | 17 | 假定每组输入只存在恰好一个解。 18 | 19 | 20 | ## 2. 示例 21 | 22 | **示例 1** 23 | 24 | ``` 25 | 输入:nums = [-1,2,1,-4], target = 1 26 | 输出:2 27 | 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:nums = [0,0,0], target = 1 34 | 输出:0 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `3 <= nums.length <= 1000` 40 | - `-1000 <= nums[i] <= 1000` 41 | - `-10^4 <= target <= 10^4` 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class ThreeSumClosest { 47 | func threeSumClosest(_ nums: [Int], _ target: Int) -> Int { 48 | var minDiff = Int.max 49 | 50 | let nums = nums.sorted() 51 | 52 | for i in 0.. 0 { 68 | repeat { 69 | right -= 1 70 | } while left < right && nums[right] == nums[right + 1] 71 | } else { 72 | repeat { 73 | left += 1 74 | } while left < right && nums[left] == nums[left - 1] 75 | } 76 | } 77 | } 78 | } 79 | 80 | return target + minDiff 81 | } 82 | } 83 | ``` 84 | 85 | * 主要思想:对数组进行排序,并在更新 diff 时对其进行迭代,根据它们的和大于或小于目标而向左递增或向右递减 86 | * 时间复杂度: O(n^2) 87 | * 空间复杂度: O(nC3) 88 | 89 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 90 | 91 | 点击前往 [LeetCode](https://leetcode.com/problems/3sum-closest "LeetCode") 练习 92 | 93 | ## 关于我们 94 | 95 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 96 | 97 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 98 | 99 | Swift社区 100 | 101 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 102 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 103 | 104 | -------------------------------------------------------------------------------- /LeetCode/#51 N 皇后.md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 50 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | **n 皇后问题** 研究的是如何将 `n` 个皇后放置在 `n×n` 的棋盘上,并且使皇后彼此之间不能相互攻击。 16 | 17 | 给你一个整数 `n` ,返回所有不同的 **n 皇后问题** 的解决方案。 18 | 19 | 每一种解法包含一个不同的 **n 皇后问题** 的棋子放置方案,该方案中 `'Q'` 和 `'.'` 分别代表了皇后和空位。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:n = 4 27 | 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 28 | 解释:如上图所示,4 皇后问题存在两个不同的解法。 29 | ``` 30 | 31 | **示例 2** 32 | 33 | ``` 34 | 输入:n = 1 35 | 输出:[["Q"]] 36 | ``` 37 | 38 | **约束条件:** 39 | 40 | - `1 <= n <= 9` 41 | 42 | ## 3. 答案 43 | 44 | ```swift 45 | class NQueens { 46 | func solveNQueens(_ n: Int) -> [[String]] { 47 | guard n > 0 else { 48 | return [[String]]() 49 | } 50 | 51 | var boards = [[String]]() 52 | var board = Array(repeating: "", count: n) 53 | 54 | dfs(&boards, &board, n, 0) 55 | 56 | return boards 57 | } 58 | 59 | private func dfs(_ boards: inout [[String]], _ board: inout [String], _ n: Int, _ row: Int) { 60 | if row == n { 61 | boards.append(Array(board)) 62 | return 63 | } 64 | 65 | 66 | for col in 0.. Bool { 75 | var c = -1 76 | 77 | for i in 0.. Character { 100 | return str[str.index(str.startIndex, offsetBy: index)] 101 | } 102 | 103 | private func setRow(_ col: Int, _ n: Int) -> String { 104 | var row = "" 105 | 106 | for i in 0.. 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | 给你一个链表,每 `k` 个节点一组进行翻转,请你返回翻转后的链表。 16 | 17 | `k` 是一个正整数,它的值小于或等于链表的长度。 18 | 19 | 如果节点总数不是 `k` 的整数倍,那么请将最后剩余的节点保持原有顺序。 20 | 21 | **进阶:** 22 | 23 | * 你可以设计一个只使用常数额外空间的算法来解决此问题吗? 24 | * **你不能只是单纯的改变节点内部的值**,而是需要实际进行节点交换。 25 | 26 | 27 | ## 2. 示例 28 | 29 | **示例 1** 30 | 31 | ![](https://images.xiaozhuanlan.com/photo/2022/e7ffe2c592e735c37fd28ed34ffd2e68.jpg) 32 | 33 | ``` 34 | 输入:head = [1,2,3,4,5], k = 2 35 | 输出:[2,1,4,3,5] 36 | ``` 37 | 38 | **示例 2** 39 | 40 | ![](https://files.mdnice.com/user/17787/1b3ebe4c-bfcf-4bbc-8254-7431d966463b.png) 41 | 42 | ``` 43 | 输入:head = [1,2,3,4,5], k = 3 44 | 输出:[3,2,1,4,5] 45 | ``` 46 | 47 | **示例 3** 48 | 49 | ``` 50 | 输入:head = [1,2,3,4,5], k = 1 51 | 输出:[1,2,3,4,5] 52 | ``` 53 | 54 | **示例 4** 55 | 56 | ``` 57 | 输入:head = [1], k = 1 58 | 输出:[1] 59 | ``` 60 | 61 | **约束条件:** 62 | 63 | - 列表中节点的数量在范围 `sz` 内 64 | - `1 <= sz <= 5000` 65 | - `0 <= Node.val <= 1000` 66 | - `1 <= k <= sz` 67 | 68 | ## 3. 答案 69 | 70 | ```swift 71 | /** 72 | * Definition for singly-linked list. 73 | * struct ListNode { 74 | * int val; 75 | * ListNode *next; 76 | * ListNode() : val(0), next(nullptr) {} 77 | * ListNode(int x) : val(x), next(nullptr) {} 78 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 79 | * }; 80 | */ 81 | class ReverseNodesInKGroup { 82 | func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? { 83 | let dummy = ListNode(0) 84 | dummy.next = head 85 | 86 | var prev = dummy // prev = A 87 | while prev.next != nil { // A->B->C->D->E => A->D->C->B->E 88 | var groupTail : ListNode? = prev 89 | for _ in 1...k { 90 | groupTail = groupTail?.next 91 | } 92 | guard let _ = groupTail else { // groupTail = D 93 | break 94 | } 95 | 96 | let nextGroupHead = groupTail!.next // nextGroupHead = E 97 | var last = nextGroupHead // last = E 98 | var current : ListNode? = prev.next // current = B 99 | while current != nil && current !== nextGroupHead { 100 | let next = current!.next // next = C 101 | current!.next = last // B -> E 102 | last = current // last = B 103 | current = next // current = C 104 | } 105 | 106 | groupTail = prev.next 107 | prev.next = last 108 | prev = groupTail! 109 | } 110 | 111 | return dummy.next 112 | } 113 | } 114 | ``` 115 | 116 | * 主要思想:在一个循环中反转一组。 从后往前构造一个反向组。 117 | * 时间复杂度: O(n) 118 | * 空间复杂度: O(1) 119 | 120 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 121 | 122 | 点击前往 [LeetCode](https://leetcode.com/problems/reverse-nodes-in-k-group/ "LeetCode") 练习 123 | 124 | ## 关于我们 125 | 126 | 我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。 127 | 128 | 后续还会翻译大量资料到我们公众号,有感兴趣的朋友,可以加入我们。 129 | -------------------------------------------------------------------------------- /LeetCode/#4 求两个有序数组的中间值.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 3 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:困难 10 | 11 | ## 描述 12 | 13 | 已知两个有序数组 `nums1` 和 `nums2`,他们的数据长度分别是 `n` 和 `m`,将两个数组合并成一个新数组,返回新数组的中间值。 14 | 15 | 整体的运行时间复杂度应该是 `O(log (m+n))` 16 | 17 | ## 示例 18 | 19 | **示例 1** 20 | 21 | ``` 22 | 输入:nums1 = [1,3], nums2 = [2] 23 | 输出:2.00000 24 | 说明:合并后的新数组为 [1,2,3],中间值为 2 25 | ``` 26 | 27 | **示例 2** 28 | 29 | ``` 30 | 输入:nums1 = [1,2], nums2 = [3,4] 31 | 输出:2.50000 32 | 说明:合并后的新数组为 [1,2,3,4],中间值为 (2 + 3) / 2 = 2.5 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:nums1 = [0,0], nums2 = [0,0] 39 | 输出:0.00000 40 | ``` 41 | 42 | **示例 4** 43 | 44 | ``` 45 | 输入:nums1 = [], nums2 = [1] 46 | 输出:1.00000 47 | ``` 48 | 49 | **示例 5** 50 | 51 | ``` 52 | 输入:nums1 = [2], nums2 = [] 53 | 输出:2.00000 54 | ``` 55 | 56 | **限制** 57 | 58 | * nums1.length == m 59 | * nums2.length == n 60 | * 0 <= m <= 1000 61 | * 0 <= n <= 1000 62 | * 1 <= m + n <= 2000 63 | * -106 <= nums1[i], nums2[i] <= 106 64 | 65 | ## 答案 66 | 67 | ```swift 68 | class Solution { 69 | func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double { 70 | let m = nums1.count 71 | let n = nums2.count 72 | 73 | if m > n { 74 | return findMedianSortedArrays(nums2, nums1) 75 | } 76 | 77 | var halfLength: Int = (m + n + 1) >> 1 78 | var b = 0, e = m 79 | var maxOfLeft = 0 80 | var minOfRight = 0 81 | 82 | while b <= e { 83 | let mid1 = (b + e) >> 1 84 | let mid2 = halfLength - mid1 85 | 86 | if mid1 > 0 && mid2 < n && nums1[mid1 - 1] > nums2[mid2] { 87 | e = mid1 - 1 88 | } else if mid2 > 0 && mid1 < m && nums1[mid1] < nums2[mid2 - 1] { 89 | b = mid1 + 1 90 | } else { 91 | if mid1 == 0 { 92 | maxOfLeft = nums2[mid2 - 1] 93 | } else if mid2 == 0 { 94 | maxOfLeft = nums1[mid1 - 1] 95 | } else { 96 | maxOfLeft = max(nums1[mid1 - 1], nums2[mid2 - 1]) 97 | } 98 | 99 | if (m + n) % 2 == 1 { 100 | return Double(maxOfLeft) 101 | } 102 | 103 | if mid1 == m { 104 | minOfRight = nums2[mid2] 105 | } else if mid2 == n { 106 | minOfRight = nums1[mid1] 107 | } else { 108 | minOfRight = min(nums1[mid1], nums2[mid2]) 109 | } 110 | 111 | break 112 | } 113 | } 114 | return Double(maxOfLeft + minOfRight) / 2.0 115 | } 116 | } 117 | ``` 118 | 119 | * 时间复杂度:O(log(n + m)) 120 | * 空间复杂度:O(1) 121 | * 主要思想:** 对于 m 和 n 数字的数组,`nums1` 和 `nums2`,其中 `m <= n`。要在 `nums1` 中找到 `mid1` 的索引,将数组分成左右部分: 122 | 123 | `nums1[0, 1, ..., mid1 - 1]` | `nums1[mid1, mid1 + 1, ..., m]` 124 | 125 | `nums2[0, 1, ..., mid2 - 1]` | `nums2[mid2, mid2 + 1, ..., n]` 126 | 127 | 数组分后的左右部分要确保: 128 | 129 | * 左数 = 右数 130 | * 左边的最大值 <= 右边的最小值 131 | 132 | 点击**阅读原文**前往 LeetCode 练习 https://leetcode.com/problems/median-of-two-sorted-arrays/ 133 | 134 | 该算法题解的 github 仓库地址是:[https://github.com/soapyigu/LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") -------------------------------------------------------------------------------- /LeetCode/#79 单词搜索(Top 100).md: -------------------------------------------------------------------------------- 1 | ![](https://upload-images.jianshu.io/upload_images/2829694-8d80389416deefc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | 3 | ## 前言 4 | 5 | **本题为 LeetCode 前 100 高频题** 6 | 7 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 8 | 9 | LeetCode 算法到目前我们已经更新了 78 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 10 | 11 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 12 | 13 | > 难度水平:中等 14 | 15 | ## 1. 描述 16 | 17 | 给定一个 `m x n` 二维字符网格 `board` 和一个字符串单词 `word` 。如果 `word` 存在于网格中,返回 `true` ;否则,返回 `false` 。 18 | 19 | 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ![](https://images.xiaozhuanlan.com/photo/2022/01dc86a2e8777fa372b18296e334142b.png) 26 | 27 | ``` 28 | 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 29 | 输出:true 30 | ``` 31 | 32 | **示例 2** 33 | 34 | ![](https://images.xiaozhuanlan.com/photo/2022/07d5e0146bf7c3eeb14504736ed338c0.png) 35 | 36 | ``` 37 | 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" 38 | 输出:true 39 | ``` 40 | **示例 3** 41 | 42 | ![](https://files.mdnice.com/user/17787/5d692bd2-0e4b-42cc-8bba-474a600acc8f.png) 43 | 44 | ``` 45 | 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB" 46 | 输出:false 47 | ``` 48 | 49 | **约束条件:** 50 | 51 | - `m == board.length` 52 | - `n = board[i].length` 53 | - `1 <= m, n <= 6` 54 | - `1 <= word.length <= 15` 55 | - `board` 和 `word` 仅由大小写英文字母组成 56 | 57 | ## 3. 答案 58 | 59 | ```swift 60 | class WordSearch { 61 | func exist(board: [[Character]], _ word: String) -> Bool { 62 | guard board.count > 0 && board[0].count > 0 else { 63 | return false 64 | } 65 | 66 | let m = board.count 67 | let n = board[0].count 68 | var visited = Array(count: m, repeatedValue: Array(count: n, repeatedValue: false)) 69 | var wordContent = [Character](word.characters) 70 | 71 | for i in 0.. Bool { 83 | if index == wordContent.count { 84 | return true 85 | } 86 | 87 | guard i >= 0 && i < m && j >= 0 && j < n else { 88 | return false 89 | } 90 | guard !visited[i][j] && board[i][j] == wordContent[index] else { 91 | return false 92 | } 93 | 94 | visited[i][j] = true 95 | 96 | if _dfs(board, wordContent, m, n, i + 1, j, &visited, index + 1) || _dfs(board, wordContent, m, n, i - 1, j, &visited, index + 1) || _dfs(board, wordContent, m, n, i, j + 1, &visited, index + 1) || _dfs(board, wordContent, m, n, i, j - 1, &visited, index + 1) { 97 | return true 98 | } 99 | visited[i][j] = false 100 | 101 | return false 102 | } 103 | } 104 | ``` 105 | 106 | * 主要思想:经典深度优先搜索,上,下,左,右四个方向。 107 | * 时间复杂度: O(mn * 4^(k - 1)), m和n分别代表矩阵的宽和高,k为单词大小 108 | * 空间复杂度: O(mn) 109 | 110 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 111 | 112 | 点击前往 [LeetCode](https://leetcode.com/problems/word-search/ "LeetCode") 练习 113 | 114 | ## 关于我们 115 | 116 | 公众号是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。欢迎关注公众号:**Swift社区**,后台点击进群,联系我们获取更多内容。 117 | 118 | Swift社区 119 | -------------------------------------------------------------------------------- /LeetCode/#20 有效的括号.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 16 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给定一个仅包含数字 `2-9` 的字符串,返回所有它能表示的字母组合。答案可以按 **任意顺序** 返回。 14 | 15 | 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 16 | 17 | ![](https://files.mdnice.com/user/17787/63ee174e-3b94-4338-b775-fdcb850bc01b.png) 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:digits = "23" 25 | 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:digits = "" 32 | 输出:[] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:digits = "2" 39 | 输出:["a","b","c"] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - `0 <= digits.length <= 4` 45 | - `digits[i]` 是范围 `['2', '9']` 的一个数字 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class LetterCombinationsPhoneNumber { 51 | func letterCombinations(_ digits: String) -> [String] { 52 | guard digits.count > 0 else { 53 | return [String]() 54 | } 55 | 56 | var combinations = [String](), combination = "" 57 | let numberToStr = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"] 58 | 59 | dfs(&combinations, &combination, numberToStr, digits, 0) 60 | 61 | return combinations 62 | } 63 | 64 | private func dfs(_ combinations: inout [String], _ combination: inout String, _ numberToStr: [String], _ digits: String, _ index: Int) { 65 | if combination.count == digits.count { 66 | combinations.append(combination) 67 | return 68 | } 69 | 70 | let currentStr = fetchCurrentStr(from: digits, at: index, numberToStr) 71 | 72 | for char in currentStr { 73 | combination.append(char) 74 | dfs(&combinations, &combination, numberToStr, digits, index + 1) 75 | combination.removeLast() 76 | } 77 | } 78 | 79 | private func fetchCurrentStr(from digits: String, at index: Int, _ numberToStr: [String]) -> String { 80 | guard index >= 0 && index < digits.count else { 81 | fatalError("Invalid index") 82 | } 83 | 84 | let currentDigitChar = digits[digits.index(digits.startIndex, offsetBy: index)] 85 | 86 | guard let currentDigit = Int(String(currentDigitChar)), currentDigit >= 0, currentDigit < numberToStr.count else { 87 | fatalError("Invalid digits") 88 | } 89 | 90 | return numberToStr[currentDigit] 91 | } 92 | } 93 | ``` 94 | 95 | * 主要思想:经典的深度优先搜索,首先创建电话板 96 | * 时间复杂度: O(4^n), n 表示数字长度 97 | * 空间复杂度: O(n), n 表示数字长度 98 | 99 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 100 | 101 | 点击前往 [LeetCode](https://leetcode.com/problems/letter-combinations-of-a-phone-number "LeetCode") 练习 102 | 103 | ## 关于我们 104 | 105 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 106 | 107 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 108 | 109 | Swift社区 110 | 111 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 112 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 113 | 114 | 115 | -------------------------------------------------------------------------------- /LeetCode/#17 电话号码的字母组合.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 16 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给定一个仅包含数字 `2-9` 的字符串,返回所有它能表示的字母组合。答案可以按 **任意顺序** 返回。 14 | 15 | 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 16 | 17 | ![](https://files.mdnice.com/user/17787/63ee174e-3b94-4338-b775-fdcb850bc01b.png) 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:digits = "23" 25 | 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"] 26 | ``` 27 | 28 | **示例 2** 29 | 30 | ``` 31 | 输入:digits = "" 32 | 输出:[] 33 | ``` 34 | 35 | **示例 3** 36 | 37 | ``` 38 | 输入:digits = "2" 39 | 输出:["a","b","c"] 40 | ``` 41 | 42 | **约束条件:** 43 | 44 | - `0 <= digits.length <= 4` 45 | - `digits[i]` 是范围 `['2', '9']` 的一个数字 46 | 47 | ## 3. 答案 48 | 49 | ```swift 50 | class LetterCombinationsPhoneNumber { 51 | func letterCombinations(_ digits: String) -> [String] { 52 | guard digits.count > 0 else { 53 | return [String]() 54 | } 55 | 56 | var combinations = [String](), combination = "" 57 | let numberToStr = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"] 58 | 59 | dfs(&combinations, &combination, numberToStr, digits, 0) 60 | 61 | return combinations 62 | } 63 | 64 | private func dfs(_ combinations: inout [String], _ combination: inout String, _ numberToStr: [String], _ digits: String, _ index: Int) { 65 | if combination.count == digits.count { 66 | combinations.append(combination) 67 | return 68 | } 69 | 70 | let currentStr = fetchCurrentStr(from: digits, at: index, numberToStr) 71 | 72 | for char in currentStr { 73 | combination.append(char) 74 | dfs(&combinations, &combination, numberToStr, digits, index + 1) 75 | combination.removeLast() 76 | } 77 | } 78 | 79 | private func fetchCurrentStr(from digits: String, at index: Int, _ numberToStr: [String]) -> String { 80 | guard index >= 0 && index < digits.count else { 81 | fatalError("Invalid index") 82 | } 83 | 84 | let currentDigitChar = digits[digits.index(digits.startIndex, offsetBy: index)] 85 | 86 | guard let currentDigit = Int(String(currentDigitChar)), currentDigit >= 0, currentDigit < numberToStr.count else { 87 | fatalError("Invalid digits") 88 | } 89 | 90 | return numberToStr[currentDigit] 91 | } 92 | } 93 | ``` 94 | 95 | * 主要思想:经典的深度优先搜索,首先创建电话板 96 | * 时间复杂度: O(4^n), n 表示数字长度 97 | * 空间复杂度: O(n), n 表示数字长度 98 | 99 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 100 | 101 | 点击前往 [LeetCode](https://leetcode.com/problems/letter-combinations-of-a-phone-number "LeetCode") 练习 102 | 103 | ## 关于我们 104 | 105 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 106 | 107 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 108 | 109 | Swift社区 110 | 111 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 112 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 113 | 114 | 115 | -------------------------------------------------------------------------------- /LeetCode/#23 合并 K 个升序链表(Top 100).md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | **本题为 LeetCode 前 100 高频题** 4 | 5 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 6 | 7 | LeetCode 算法到目前我们已经更新了 22 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 8 | 9 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 10 | 11 | > 难度水平:困难 12 | 13 | ## 1. 描述 14 | 15 | 给你一个链表数组,每个链表都已经按升序排列。 16 | 17 | 请你将所有链表合并到一个升序链表中,返回合并后的链表。 18 | 19 | ## 2. 示例 20 | 21 | **示例 1** 22 | 23 | ``` 24 | 输入:lists = [[1,4,5],[1,3,4],[2,6]] 25 | 输出:[1,1,2,3,4,4,5,6] 26 | 解释:链表数组如下: 27 | [ 28 | 1->4->5, 29 | 1->3->4, 30 | 2->6 31 | ] 32 | 将它们合并到一个有序链表中得到。 33 | 1->1->2->3->4->4->5->6 34 | ``` 35 | 36 | **示例 2** 37 | 38 | ``` 39 | 输入:lists = [] 40 | 输出:[] 41 | ``` 42 | 43 | **示例 3** 44 | 45 | ``` 46 | 输入:lists = [[]] 47 | 输出:[] 48 | ``` 49 | 50 | **约束条件:** 51 | 52 | - `k == lists.length` 53 | - `0 <= k <= 10^4` 54 | - `0 <= lists[i].length <= 500` 55 | - `-10^4 <= lists[i][j] <= 10^4` 56 | - `lists[i]` 按 **升序** 排列 57 | - `lists[i].length` 的总和不超过 `10^4` 58 | 59 | ## 3. 答案 60 | 61 | ```swift 62 | /** 63 | * Definition for singly-linked list. 64 | * struct ListNode { 65 | * int val; 66 | * ListNode *next; 67 | * ListNode() : val(0), next(nullptr) {} 68 | * ListNode(int x) : val(x), next(nullptr) {} 69 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 70 | * }; 71 | */ 72 | class MergeKSortedLists { 73 | func mergeKLists(lists: [ListNode?]) -> ListNode? { 74 | guard lists.count > 0 else { 75 | return nil 76 | } 77 | 78 | var left = 0 79 | var right = lists.count - 1 80 | 81 | var lists = lists 82 | 83 | while right > 0 { 84 | left = 0 85 | while left < right { 86 | lists[left] = _mergeTwoLists(lists[left], lists[right]) 87 | left += 1 88 | right -= 1 89 | } 90 | } 91 | 92 | return lists[0] 93 | } 94 | 95 | private func _mergeTwoLists(l1: ListNode?, _ l2: ListNode?) -> ListNode? { 96 | let dummy = ListNode(0) 97 | var node = dummy 98 | 99 | var l1 = l1 100 | var l2 = l2 101 | 102 | while l1 != nil && l2 != nil { 103 | if l1!.val < l2!.val { 104 | node.next = l1 105 | l1 = l1!.next 106 | } else { 107 | node.next = l2 108 | l2 = l2!.next 109 | } 110 | 111 | node = node.next! 112 | } 113 | 114 | node.next = l1 ?? l2 115 | 116 | return dummy.next 117 | } 118 | } 119 | ``` 120 | 121 | * 主要思想:Dummy Node来遍历两个列表,比较两个节点并指向右边的一个。 122 | * 时间复杂度: O(mlogn) m 表示一个列表的长度,n 表示列表的个数。 123 | * 空间复杂度: O(1) 124 | 125 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 126 | 127 | 点击前往 [LeetCode](https://leetcode.com/problems/merge-k-sorted-lists/ "LeetCode") 练习 128 | 129 | ## 关于我们 130 | 131 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 132 | 133 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 134 | 135 | Swift社区 136 | 137 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 138 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 139 | 140 | 141 | -------------------------------------------------------------------------------- /LeetCode/#13 罗马数字转整数.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 12 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:简单 10 | 11 | ## 1. 描述 12 | 13 | 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 14 | 15 | 字符 | 数值 16 | ----|------ 17 | Amazon | ★★ 18 | I | 1 19 | V | 5 20 | X | 10 21 | L | 50 22 | C | 100 23 | D | 500 24 | M | 1000 25 | 26 | 例如, 罗马数字 2 写做 `II` ,即为两个并列的 1。12 写做 `XII` ,即为 `X` + `II` 。 `27` 写做 `XXVII`, 即为 `XX` + `V` + `II`。 27 | 28 | 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 `IIII`,而是 `IV`。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 `IX`。这个特殊的规则只适用于以下六种情况: 29 | 30 | * `I` 可以放在 `V` (5) 和 `X` (10) 的左边,来表示 4 和 9。 31 | * `X` 可以放在 `L` (50) 和 `C` (100) 的左边,来表示 40 和 90。 32 | * `C` 可以放在 `D` (500) 和 `M` (1000) 的左边,来表示 400 和 900。 33 | 34 | 给定一个罗马数字,将其转换成整数。 35 | 36 | ## 2. 示例 37 | 38 | **示例 1** 39 | 40 | ``` 41 | 输入: s = "III" 42 | 输出: 3 43 | ``` 44 | 45 | **示例 2** 46 | 47 | ``` 48 | 输入: s = "IV" 49 | 输出: 4 50 | ``` 51 | 52 | **示例 3** 53 | 54 | ``` 55 | 输入: s = "IX" 56 | 输出: 9 57 | ``` 58 | 59 | **示例 4** 60 | 61 | ``` 62 | 输入: s = "LVIII" 63 | 输出: 58 64 | 解释: L = 50, V= 5, III = 3. 65 | ``` 66 | 67 | **示例 5** 68 | 69 | ``` 70 | 输入: s = "MCMXCIV" 71 | 输出: 1994 72 | 解释: M = 1000, CM = 900, XC = 90, IV = 4. 73 | ``` 74 | 75 | **约束条件:** 76 | 77 | - `1 <= s.length <= 15` 78 | - `s` 仅含字符 `('I', 'V', 'X', 'L', 'C', 'D', 'M')` 79 | - 题目数据保证 `s` 是一个有效的罗马数字,且表示整数在范围 `[1, 3999]` 内 80 | - 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况 81 | - `IL` 和 `IM` 这样的例子并不符合题目要求,`49` 应该写作 `XLIX`,`999` 应该写作 `CMXCIX` 82 | - 关于罗马数字的详尽书写规则,可以参考 [罗马数字 - Mathematics](https://b2b.partcommunity.com/community/knowledge/zh_CN/detail/10753/罗马数字#knowledge_article "罗马数字 - Mathematics") 83 | 84 | ## 3. 答案 85 | 86 | ```swift 87 | class RomanToInteger { 88 | func romanToInt(s: String) -> Int { 89 | let dict = initDict() 90 | let chars = [Character](s.characters.reverse()) 91 | var res = 0 92 | 93 | for i in 0.. 0 && current < dict[String(chars[i - 1])] { 98 | res -= current 99 | } else { 100 | res += current 101 | } 102 | } 103 | 104 | return res 105 | } 106 | 107 | private func initDict() -> [String: Int] { 108 | var dict = [String: Int]() 109 | 110 | dict["I"] = 1 111 | dict["V"] = 5 112 | dict["X"] = 10 113 | dict["L"] = 50 114 | dict["C"] = 100 115 | dict["D"] = 500 116 | dict["M"] = 1000 117 | 118 | return dict 119 | } 120 | } 121 | ``` 122 | 123 | * 主要思想:从头到尾进行迭代,根据不同情况进行添加或减去 124 | * 时间复杂度: O(n) 125 | * 空间复杂度: O(n) 126 | 127 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 128 | 129 | 点击前往 [LeetCode](https://leetcode.com/problems/roman-to-integer/ "LeetCode") 练习 130 | 131 | ## 关于我们 132 | 133 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 134 | 135 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 136 | 137 | Swift社区 138 | 139 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 140 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩") 141 | 142 | -------------------------------------------------------------------------------- /LeetCode/#12 整数转罗马数字.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 11 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 14 | 15 | 字符 | 数值 16 | ----|------ 17 | Amazon | ★★ 18 | I | 1 19 | V | 5 20 | X | 10 21 | L | 50 22 | C | 100 23 | D | 500 24 | M | 1000 25 | 26 | 例如, 罗马数字 2 写做 `II` ,即为两个并列的 1。12 写做 `XII` ,即为 `X` + `II` 。 27 写做 `XXVII`, 即为 `XX` + `V` + `II`。 27 | 28 | 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 `IIII`,而是 `IV`。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 `IX`。这个特殊的规则只适用于以下六种情况: 29 | 30 | * `I` 可以放在 `V` (5) 和 `X` (10) 的左边,来表示 4 和 9。 31 | * `X` 可以放在 `L` (50) 和 `C` (100) 的左边,来表示 40 和 90。 32 | * `C` 可以放在 `D` (500) 和 `M` (1000) 的左边,来表示 400 和 900。 33 | 34 | 给你一个整数,将其转为罗马数字。 35 | 36 | ## 2. 示例 37 | 38 | **示例 1** 39 | 40 | ``` 41 | 输入: num = 3 42 | 输出: "III" 43 | ``` 44 | 45 | **示例 2** 46 | 47 | ``` 48 | 输入: num = 4 49 | 输出: "IV" 50 | ``` 51 | 52 | **示例 3** 53 | 54 | ``` 55 | 输入: num = 9 56 | 输出: "IX" 57 | ``` 58 | 59 | **示例 4** 60 | 61 | ``` 62 | 输入: num = 58 63 | 输出: "LVIII" 64 | 解释: L = 50, V = 5, III = 3. 65 | ``` 66 | 67 | **示例 5** 68 | 69 | ``` 70 | 输入: num = 1994 71 | 输出: "MCMXCIV" 72 | 解释: M = 1000, CM = 900, XC = 90, IV = 4. 73 | ``` 74 | 75 | **约束条件:** 76 | 77 | - `1 <= num <= 3999` 78 | 79 | 80 | ## 3. 答案 81 | 82 | ```swift 83 | class IntegerToRoman { 84 | func intToRoman(_ num: Int) -> String { 85 | guard num > 0 else { 86 | return "" 87 | } 88 | 89 | let nums = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] 90 | let symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] 91 | var res = "" 92 | var digit = 0 93 | var number = num 94 | 95 | while number > 0 { 96 | let current = number / nums[digit] 97 | 98 | for _ in 0.. String { 113 | guard num > 0 else { return "" } 114 | 115 | let thousands = ["", "M", "MM", "MMM"] 116 | let hundreds = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"] 117 | let tens = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"] 118 | let ones = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] 119 | 120 | return thousands[num / 1000] + hundreds[num % 1000 / 100] + tens[num % 100 / 10] + ones[num % 10] 121 | } 122 | } 123 | ``` 124 | 125 | * 主要思想:符号由大到小相加,同时减去相对数 126 | * 时间复杂度: O(n) 127 | * 空间复杂度: O(1) 128 | 129 | 该算法题解的仓库:[LeetCode-Swift](https://github.com/soapyigu/LeetCode-Swift "LeetCode-Swift") 130 | 131 | 点击前往 [LeetCode](https://leetcode.com/problems/integer-to-roman "LeetCode") 练习 132 | 133 | ## 关于我们 134 | 135 | **Swift社区**是由 Swift 爱好者共同维护的公益组织,我们在国内以微信公众号的运营为主,我们会分享以 **Swift实战**、**SwiftUl**、**Swift基础**为核心的技术内容,也整理收集优秀的学习资料。 136 | 137 | 欢迎关注公众号:Swift社区,后台点击进群,可以进入我们社区的各种交流讨论群。希望我们Swift社区是大家在网络空间中的另一份共同的归属。 138 | 139 | Swift社区 140 | 141 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 142 | 143 | * [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇") 144 | * [倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶") 145 | * [戴铭@快手](https://ming1016.github.io "戴铭") 146 | * [展菲@ESP](https://github.com/fanbaoying "展菲") 147 | * [杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶") 148 | * [韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦") 149 | 150 | -------------------------------------------------------------------------------- /LeetCode/#18 四数之和 .md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 我们社区陆续会将顾毅(**Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:[@故胤道长](https://m.weibo.cn/u/1827884772 "@故胤道长")**)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 4 | 5 | LeetCode 算法到目前我们已经更新了 17 期,我们会保持更新时间和进度(**周一、周三、周五早上 9:00 发布**),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。 6 | 7 | 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。**如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。** 8 | 9 | > 难度水平:中等 10 | 11 | ## 1. 描述 12 | 13 | 给你一个由 `n` 个整数组成的数组 `nums`,和一个目标值 `target` 。请你找出并返回满足下述全部条件且不重复的四元组 `[nums[a], nums[b], nums[c], nums[d]]`(若两个四元组元素一一对应,则认为两个四元组重复): 14 | 15 | * `0 <= a, b, c, d < n` 16 | * `a`、`b`、`c` 和 `d` 互不相同 17 | * `nums[a] + nums[b] + nums[c] + nums[d] == target` 18 | 19 | 你可以按 **任意顺序** 返回答案。 20 | 21 | ## 2. 示例 22 | 23 | **示例 1** 24 | 25 | ``` 26 | 输入:nums = [1,0,-1,0,-2,2], target = 0 27 | 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]] 28 | ``` 29 | 30 | **示例 2** 31 | 32 | ``` 33 | 输入:nums = [2,2,2,2,2], target = 8 34 | 输出:[[2,2,2,2]] 35 | ``` 36 | 37 | **约束条件:** 38 | 39 | - `1 <= nums.length <= 200` 40 | - `-109 <= nums[i] <= 109` 41 | - `-109 <= target <= 109` 42 | 43 | ## 3. 答案 44 | 45 | ```swift 46 | class FourSum { 47 | func fourSum(_ nums: [Int], _ target: Int) -> [[Int]] { 48 | let nums = nums.sorted(by: <) 49 | var threeSum = 0 50 | var twoSum = 0 51 | var left = 0 52 | var right = 0 53 | var res = [[Int]]() 54 | 55 | guard nums.count >= 4 else { 56 | return res 57 | } 58 | 59 | for i in 0.. 115 | 116 | 特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量,排名不分先后: 117 | [张安宇@微软](https://blog.csdn.net/mobanchengshuang "张安宇")、[戴铭@快手](https://ming1016.github.io "戴铭")、[展菲@ESP](https://github.com/fanbaoying "展菲")、[倪瑶@Trip.com](https://github.com/niyaoyao "倪瑶")、[杜鑫瑶@新浪](https://weibo.com/u/3878455011 "杜鑫瑶")、[韦弦@Gwell](https://www.jianshu.com/u/855d6ea2b3d1 "韦弦")、[张浩@讯飞](https://github.com/zhanghao19920218 "张浩")、[张星宇@ByteDance](https://github.com/bestswifter "张星宇")、[郭英东@便利蜂](https://github.com/EmingK "郭英东") 118 | 119 | 120 | --------------------------------------------------------------------------------