102道LeetCode题解全解析:Swift 5编程范式与算法优化实战指南

102道LeetCode题解全解析:Swift 5编程范式与算法优化实战指南

【免费下载链接】LeetCode-Solutions-in-Swift LeetCode Solutions in Swift 5 【免费下载链接】LeetCode-Solutions-in-Swift 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Solutions-in-Swift

你是否还在为Swift算法面试题挠头?面对LeetCode上纷繁复杂的解题思路,是否渴望一套既符合Swift语言特性又保证最优时间/空间复杂度的权威指南?本文将带你深入剖析102道LeetCode经典题目,通过Swift 5的独特语法特性,从根本上提升你的算法思维与代码质量。

读完本文你将获得:

  • 102道LeetCode题目(Easy/Medium/Hard)的Swift 5最优解
  • 掌握Swift语言特性在算法中的实战应用(guard/defer、map/filter/reduce等)
  • 算法复杂度分析方法论(从O(N²)到O(logN)的优化路径)
  • 完整测试驱动开发(TDD)实践案例
  • 10+种数据结构与算法范式的Swift实现模板

项目架构深度解析

LeetCode-Solutions-in-Swift项目采用模块化架构设计,严格遵循Swift最佳实践,构建了一套可扩展的算法解决方案体系。项目核心结构如下:

LeetCode-Solutions-in-Swift/
├── LICENSE
├── README.md
└── Solutions/
    ├── Solutions.xcodeproj/        # Xcode项目配置
    ├── Solutions/                  # 核心代码目录
    │   ├── Easy/                   # 简单难度题目
    │   ├── Medium/                 # 中等难度题目
    │   ├── Hard/                   # 困难难度题目
    │   └── Solutions_ObjC/         # Objective-C对比实现
    └── SolutionsTests/             # 单元测试目录
        ├── Easy/
        ├── Medium/
        └── Hard/

核心技术特点

该项目区别于其他算法仓库的四大优势:

  1. Swift原生优化:充分利用Swift语言特性,如可选类型(Optional)、扩展(Extension)、泛型(Generics)等,实现更简洁优雅的代码

  2. 严格复杂度控制:所有解决方案均保证最优时间/空间复杂度,例如二叉树中序遍历的O(1)空间实现

  3. 双语言对照:部分题目提供Swift与Objective-C双实现,便于理解两种语言的范式差异

  4. 全面测试覆盖:每个算法配备多组测试用例,包括边界条件、性能压力测试等

mermaid

Swift算法实现范式

哈希表应用:Two Sum问题的Swift实现

Two Sum作为LeetCode开篇第一题(Medium难度),其最优解法充分体现了哈希表在空间换时间策略中的经典应用。该项目采用Swift字典(Dictionary)实现O(N)时间复杂度的解决方案:

struct Medium_001_Two_Sum {
    // t = O(N), s = O(N)
    static func twoSum(numbers: [Int], target: Int) -> [Int] {
        var hashMap = [Int: Int]()  // 存储值到索引的映射
        var result = [Int]()

        for i in 0..<numbers.count {
            let numberToFind: Int = target - numbers[i]
            // 检查差值是否已存在于哈希表中
            if let numberToFindIndex = hashMap[numberToFind] {
                result.append(numberToFindIndex + 1)  // 题目要求非零基索引
                result.append(i + 1)
                return result
            } else {
                hashMap[numbers[i]] = i  // 存储当前值及其索引
            }
        }
        return result
    }
}
测试用例设计

单元测试采用XCTest框架,通过多场景覆盖确保算法正确性:

func test_001() {
    let input0: [Int] = [2, 7, 11, 15]
    let input1: Int = 9
    let expected: [Int] = [1, 2]
    asyncHelper(input0: input0, input1: input1, expected: expected)
}

func test_002() {
    let input0: [Int] = [5, 5]  // 处理重复元素
    let input1: Int = 10
    let expected: [Int] = [1, 2]
    asyncHelper(input0: input0, input1: input1, expected: expected)
}

func test_003() {
    let input0: [Int] = [5, 7, 5, 2, 11, 15]  // 多个潜在解
    let input1: Int = 9
    let expected: [Int] = [2, 4]  // 确保返回最前的有效解
    asyncHelper(input0: input0, input1: input1, expected: expected)
}
Swift vs Objective-C实现对比
特性Swift实现Objective-C实现
类型安全编译时严格类型检查运行时动态类型
代码简洁度30行(含注释)55行(含注释)
内存管理ARC自动管理,无需显式释放需要手动管理或使用ARC
集合操作原生Dictionary类型NSDictionary,需处理nil

字符串操作:ZigZag Conversion的Swift优化

第6题ZigZag Conversion(Easy难度)展示了Swift字符串处理的独特优势。由于Swift字符串不支持下标随机访问(因采用扩展 grapheme 簇存储),项目实现了高效的字符数组转换策略:

struct Easy_006_ZigZag_Conversion {
    // t = O(N), s = O(N)
    static func convert(_ s: String, _ numRows: Int) -> String {
        guard numRows > 1 else { return s }
        
        let characters = Array(s)
        var rows = [String](repeating: "", count: numRows)
        var currentRow = 0
        var goingDown = false
        
        for char in characters {
            rows[currentRow] += String(char)
            
            // 到达边界时改变方向
            if currentRow == 0 || currentRow == numRows - 1 {
                goingDown.toggle()
            }
            
            currentRow += goingDown ? 1 : -1
        }
        
        return rows.joined()
    }
}
算法可视化

ZigZag转换过程可通过以下状态图直观理解:

mermaid

动态规划:最长回文子串的Manacher算法

第5题Longest Palindromic Substring(Medium难度)采用了Manacher算法实现O(N)时间复杂度,充分展示了Swift在复杂算法实现中的表达能力:

struct Medium_005_Longest_Palindromic_Substring {
    static func longestPalindrome(_ s: String) -> String {
        let str = preprocess(s)
        let n = str.count
        var p = [Int](repeating: 0, count: n)
        var center = 0, right = 0
        
        for i in 1..<n-1 {
            let mirror = 2 * center - i
            
            if i < right {
                p[i] = min(right - i, p[mirror])
            }
            
            // 尝试扩展回文
            var a = i + (1 + p[i])
            var b = i - (1 + p[i])
            
            while str[str.index(str.startIndex, offsetBy: a)] == str[str.index(str.startIndex, offsetBy: b)] {
                p[i] += 1
                a += 1
                b -= 1
            }
            
            // 更新中心和右边界
            if i + p[i] > right {
                center = i
                right = i + p[i]
            }
        }
        
        // 找到最长回文
        var maxLen = 0, centerIndex = 0
        for i in 1..<n-1 {
            if p[i] > maxLen {
                maxLen = p[i]
                centerIndex = i
            }
        }
        
        let start = str.index(str.startIndex, offsetBy: (centerIndex - maxLen))
        let end = str.index(str.startIndex, offsetBy: (centerIndex + maxLen))
        let subStr = str[start..<end]
        return String(subStr.filter { $0 != "#" })
    }
    
    private static func preprocess(_ s: String) -> String {
        guard !s.isEmpty else { return "^$" }
        var result = "^"
        for char in s {
            result += "#\(char)"
        }
        result += "#$"
        return result
    }
}

测试驱动开发实践

项目采用XCTest框架实现全面的测试覆盖,每个算法至少包含3组测试用例:基本功能测试、边界条件测试和性能压力测试。以Two Sum的测试实现为例:

class Medium_001_Two_Sum_Test: XCTestCase, SolutionsTestCase {
    func test_001() {
        let input0: [Int] = [2, 7, 11, 15]
        let input1: Int = 9
        let expected: [Int] = [1, 2]
        asyncHelper(input0: input0, input1: input1, expected: expected)
    }
    
    func test_002() {
        let input0: [Int] = [5, 5]  // 重复元素测试
        let input1: Int = 10
        let expected: [Int] = [1, 2]
        asyncHelper(input0: input0, input1: input1, expected: expected)
    }
    
    func test_003() {
        let input0: [Int] = [5, 7, 5, 2, 11, 15]  // 多个潜在解测试
        let input1: Int = 9
        let expected: [Int] = [2, 4]
        asyncHelper(input0: input0, input1: input1, expected: expected)
    }
    
    // 异步测试辅助函数
    private func asyncHelper(input0: [Int], input1: Int, expected: [Int]) {
        weak var expectation: XCTestExpectation? = self.expectation(description: timeOutName())
        
        serialQueue().async {
            let result_swift = Medium_001_Two_Sum.twoSum(numbers: input0, target: input1)
            let result_objc = ObjC_Medium_001_Two_Sum.twoSum(input0 as [NSNumber], target: input1)
            
            // 验证Swift实现
            assertHelper(expected == result_swift, 
                        problemName: self.problemName(), 
                        input: input0, 
                        resultValue: result_swift, 
                        expectedValue: expected)
            
            // 验证Objective-C实现
            let result_objc_Int = result_objc.map { $0.intValue }
            assertHelper(result_objc_Int == expected,
                        problemName: self.problemName(),
                        input: input0,
                        resultValue: result_objc,
                        expectedValue: expected)
            
            expectation?.fulfill()
        }
        
        waitForExpectations(timeout: timeOut()) { error in
            if error != nil {
                assertHelper(false,
                            problemName: self.problemName(),
                            input: input0,
                            resultValue: self.timeOutName(),
                            expectedValue: expected)
            }
        }
    }
}

按难度分级的学习路径

入门必刷(Easy难度)

题目算法类型核心知识点时间复杂度
7. Reverse Integer数学运算整数溢出处理O(logN)
9. Palindrome Number数学运算回文判断O(logN)
13. Roman to Integer哈希表符号映射O(N)
14. Longest Common Prefix字符串垂直扫描O(N*M)
20. Valid Parentheses括号匹配O(N)
21. Merge Two Sorted Lists链表指针操作O(N+M)
26. Remove Duplicates数组双指针O(N)

进阶提升(Medium难度)

题目算法类型核心知识点时间复杂度
1. Two Sum哈希表空间换时间O(N)
2. Add Two Numbers链表进位处理O(max(N,M))
3. Longest Substring滑动窗口无重复字符O(N)
5. Longest Palindrome动态规划中心扩展O(N²)
11. Container Water双指针面积计算O(N)
15. 3Sum双指针排序去重O(N²)
17. Letter Combinations回溯法组合生成O(3^N)

面试挑战(Hard难度)

题目算法类型核心知识点时间复杂度
4. Median of Two Arrays二分查找寻找中位数O(log(min(N,M)))
10. Regular Expression动态规划模式匹配O(N*M)
23. Merge k Sorted Lists多路归并O(NlogK)
32. Longest Valid Parentheses动态规划括号匹配O(N)
42. Trapping Rain Water双指针雨水计算O(N)
76. Minimum Window Substring滑动窗口子串覆盖O(N+M)
84. Largest Rectangle直方图计算O(N)

mermaid

项目使用指南

环境要求

  • Xcode 12.4 (12D4e) 或更高版本
  • Swift 5.3 或更高版本
  • macOS 10.15 或更高版本

快速开始

  1. 克隆仓库:

    git clone https://gitcode.com/gh_mirrors/le/LeetCode-Solutions-in-Swift.git
    
  2. 打开项目:

    cd LeetCode-Solutions-in-Swift
    open Solutions/Solutions.xcodeproj
    
  3. 运行所有测试:

    • 在Xcode中按下 ⌘ + U
    • 或使用命令行:xcodebuild test -project Solutions/Solutions.xcodeproj -scheme Solutions -destination 'platform=iOS Simulator,name=iPhone 12'

测试结果分析

测试套件包含665个测试用例,覆盖所有102道题目。测试报告将显示:

  • 每个算法的执行时间
  • 内存使用情况
  • Swift与Objective-C实现的性能对比
  • 边界条件处理情况

性能优化策略

时间复杂度优化案例

以第4题Median of Two Sorted Arrays(Hard难度)为例,项目实现了O(log(min(N,M)))的最优解法,关键在于通过二分查找减少比较次数:

struct Hard_004_Median_Of_Two_Sorted_Arrays {
    static func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
        // 确保nums1是较短的数组,优化查找范围
        let (numsA, numsB) = nums1.count <= nums2.count ? (nums1, nums2) : (nums2, nums1)
        let m = numsA.count, n = numsB.count
        
        var imin = 0, imax = m, halfLen = (m + n + 1) / 2
        
        while imin <= imax {
            let i = (imin + imax) / 2
            let j = halfLen - i
            
            // 调整二分查找范围
            if i < m && numsB[j-1] > numsA[i] {
                imin = i + 1
            } else if i > 0 && numsA[i-1] > numsB[j] {
                imax = i - 1
            } else {
                // 找到正确划分
                let maxLeft: Int
                if i == 0 {
                    maxLeft = numsB[j-1]
                } else if j == 0 {
                    maxLeft = numsA[i-1]
                } else {
                    maxLeft = max(numsA[i-1], numsB[j-1])
                }
                
                // 奇数长度直接返回
                if (m + n) % 2 == 1 {
                    return Double(maxLeft)
                }
                
                // 偶数长度计算平均值
                let minRight: Int
                if i == m {
                    minRight = numsB[j]
                } else if j == n {
                    minRight = numsA[i]
                } else {
                    minRight = min(numsA[i], numsB[j])
                }
                
                return Double(maxLeft + minRight) / 2.0
            }
        }
        
        return 0.0
    }
}

空间复杂度优化:O(1)空间的二叉树遍历

第94题Binary Tree Inorder Traversal(Medium难度)展示了如何在不使用递归栈的情况下实现O(1)空间复杂度的中序遍历:

struct Medium_094_Binary_Tree_Inorder_Traversal {
    // Morris Traversal: t = O(N), s = O(1)
    static func inorderTraversal(_ root: TreeNode?) -> [Int] {
        var result = [Int]()
        var current = root
        var predecessor: TreeNode?
        
        while current != nil {
            if current?.left == nil {
                // 当前节点左子树为空,输出当前节点
                result.append(current!.val)
                current = current?.right
            } else {
                // 找到当前节点的前驱节点
                predecessor = current?.left
                while predecessor?.right != nil && predecessor?.right !== current {
                    predecessor = predecessor?.right
                }
                
                if predecessor?.right == nil {
                    // 建立线索
                    predecessor?.right = current
                    current = current?.left
                } else {
                    // 恢复树结构,输出当前节点
                    predecessor?.right = nil
                    result.append(current!.val)
                    current = current?.right
                }
            }
        }
        
        return result
    }
}

总结与展望

LeetCode-Solutions-in-Swift项目不仅提供了102道题目的最优解,更重要的是展示了如何将Swift语言特性与算法思想完美结合。通过学习这些实现,你将获得:

  1. Swift编程范式:掌握guard/defer、map/filter/reduce等高阶特性在算法中的应用
  2. 算法思维提升:从暴力解法到最优解的思考过程,培养时间/空间复杂度意识
  3. 测试驱动开发:学习如何设计全面的测试用例,确保代码正确性与鲁棒性

未来计划

  • 增加更多题目,目标覆盖LeetCode前300题
  • 添加算法复杂度可视化工具
  • 实现SwiftUI交互式算法演示
  • 提供iPadOS/iOS应用版本,支持离线学习

收藏本文,开启你的Swift算法精进之旅!如有任何问题或建议,欢迎在项目中提交issue,让我们共同打造Swift算法学习的优质资源库。

【免费下载链接】LeetCode-Solutions-in-Swift LeetCode Solutions in Swift 5 【免费下载链接】LeetCode-Solutions-in-Swift 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Solutions-in-Swift

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值