首页 > 其他分享 >Swift 实现:寻找单链表相交节点

Swift 实现:寻找单链表相交节点

时间:2024-12-13 22:30:54浏览次数:8  
标签:单链 ListNode 复杂度 相交 next 链表 Swift 节点

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

文章目录

摘要

本篇文章将分享如何通过 Swift 编写程序,找到两个单链表相交的起始节点。我们将分析问题,提供清晰的题解代码,并通过示例测试验证结果。同时,文章会详细剖析代码逻辑,评估其时间复杂度和空间复杂度,助力开发者掌握高效算法的实现技巧。

描述

编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:

在节点 c1 开始相交。

示例 1:

**输入:**intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
**输出:**Reference of the node with value = 8
**输入解释:**相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

**输入:**intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
**输出:**Reference of the node with value = 2
**输入解释:**相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

**输入:**intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
**输出:**null
**输入解释:**从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
**解释:**这两个链表不相交,因此返回 null。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

题解答案

以下为 Swift 的题解实现:

class ListNode {
    var val: Int
    var next: ListNode?

    init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}

class Solution {
    func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? {
        guard headA != nil && headB != nil else { return nil }
        
        var pointerA = headA
        var pointerB = headB
        
        while pointerA !== pointerB {
            pointerA = pointerA == nil ? headB : pointerA?.next
            pointerB = pointerB == nil ? headA : pointerB?.next
        }
        
        return pointerA
    }
}

题解代码分析

  1. 基本思路
    使用双指针法解决问题:

    • 两个指针分别从 headAheadB 开始,依次遍历链表。
    • 如果指针到达链表尾部,则切换到另一个链表的头部继续遍历。
    • 当两个指针相遇时,即为链表的相交节点;若无相交节点,则最终返回 nil
  2. 关键逻辑

    • 双指针在遍历链表时,总会同时进入交点或结束(无交点时均为 nil)。
    • 通过两次遍历,确保指针在长度不同的链表上补齐长度差异。
  3. 核心代码解析

    • pointerA = pointerA == nil ? headB : pointerA?.next
      pointerA 到达链表 A 的末尾时,切换到链表 B 的头部,反之亦然。

示例测试及结果

// 示例链表创建
let common = ListNode(8)
common.next = ListNode(4)
common.next?.next = ListNode(5)

let listA = ListNode(4)
listA.next = ListNode(1)
listA.next?.next = common

let listB = ListNode(5)
listB.next = ListNode(0)
listB.next?.next = ListNode(1)
listB.next?.next?.next = common

// 测试用例
let solution = Solution()
if let intersection = solution.getIntersectionNode(listA, listB) {
    print("Intersection Node Value: \(intersection.val)") // 输出:8
} else {
    print("No Intersection")
}

输出结果:

Intersection Node Value: 8

时间复杂度

  • 分析
    每个指针最多遍历两个链表的总长度,时间复杂度为 (O(m + n)),其中 (m) 和 (n) 分别为链表 A 和链表 B 的长度。

空间复杂度

  • 分析
    仅使用了两个指针,额外空间复杂度为 (O(1))。

总结

通过双指针法,成功实现了寻找链表相交节点的高效算法。其优势在于时间复杂度 (O(n))、空间复杂度 (O(1)) 的表现。实际应用中,该方法具有较高的通用性,非常适合处理单链表相关问题。

未来可以进一步扩展到其他链表问题,例如检测链表环、合并链表等。希望本篇文章能帮助大家更好地理解和掌握链表算法的核心技巧!

标签:单链,ListNode,复杂度,相交,next,链表,Swift,节点
From: https://blog.csdn.net/qq_36478920/article/details/144461065

相关文章

  • 苹果开发者入门:修复 SwiftUI 中“跑偏的”动画(下)
    概述大家知道SwiftUI不仅仅是一款App界面布局的超级利器,它同样提供了花样百出的动画和转场机制将UI世界点缀的“楚楚动人”。不过,对于苹果开发新入门的秃头小码农来说,使用动画貌似没有想象的那么易如反掌。如上图所示,在游戏成功和失败时红色圆形到图片的转变并没......
  • 数字组合转字母&删除二叉树节点&字符串相乘&打家劫舍ii&无序数组第k大 &无序数组前k大
    一、数字串转换为字符串1-26个数字分别代表26个字符(A-z)输入"12326〞就可以拆分为【1,2,3,2,6】、(12,3,2,6].[1,23,2,6]【1,23,26】、【12,3,26】等,将每种组合转成成对应字母输出,输出所有可能的结果返回所有可能的转换结果//将数字串转换成字母串//将数字串转换成字母......
  • 使用 Swift 实现文字识别
    使用Swift调用TesseractOCR库来识别图像中的文字。我们将通过安装Tesseract库并进行简单的集成,来完成文字识别的操作。步骤安装TesseractOCR我们将使用Tesseract库来进行OCR操作。首先,你需要在macOS上安装Tesseract。如果你使用的是macOS,可以通过Homebrew来......
  • 【双层优化】分布式光伏储能系统的优化配置方法【IEEE33节点】(Matlab代码实现)
         ......
  • 数据结构与算法之美:再谈单链表(进阶)
            Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!我的博客:<但凡.我的专栏:《数据结构与算法之美》、《编程之路》、《题海拾贝》欢迎点赞,关注! 目录 1、使用C++实现单链表1.1节点的声明1.2节点的初始化1.3头插和尾插1.3.1头插......
  • Python使用Selenium库获取 网页节点元素、名称、内容的方法
    我们要用到一些网页源码信息,例如获取一些节点的class内容,除了使用Beautifulsoup来解析,还可以直接用Selenium库打印节点(元素)名称,用来获取元素的文本内容或者标签名。例如获取下面的class的内容:以下是几种常用的方法:1.获取元素的属性值:使用元素的.get_attribute('attri......
  • 数据结构:单链表详解
    1.单链表的介绍2.单链表的使用(1)结点的头/尾部的插入和删除(2)对特定结点的查找(3)在指定位置之前/后插入和删除数据(4)销毁链表3.链表与顺序表的对比我以过客之名,祝你前程似锦一.单链表1.概念与结构:概念:链表是⼀种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑......
  • .NET MAUI开发的安卓、iOS软件和Java开发的安卓和Swift开发的iOS的区别
    1. 开发语言和平台.NETMAUI:使用 C# 作为开发语言。通过 .NET6/7/8 平台编译并打包应用。.NETMAUI 会根据目标平台(Android或iOS)编译和运行不同的本地代码。代码是跨平台的,开发者可以使用相同的代码库为Android和iOS构建应用,只需要针对平台特定功能进行少量调......
  • DataSophon1.2.1集成DataX&DataX-Web(多节点)
    DataSophon简单集成DataX&DataX-Web(多节点)DATAX部署环境准备JDK(1.8以上,推荐1.8)Python(2或3都可以,linux自带py2,py3执行脚本会报错,需要修改脚本)ApacheMaven3.x(CompileDataX,如果下载的是官方的压缩包[datax.tar.gz],不用安装这个,如果是在git拉的项目,打包时需要)安装......
  • DataSophon1.2.1集成DataX&DataX-Web(单节点)
    DataSophon集成DataX&DataX-Web(单节点)DATAX部署环境准备JDK(1.8以上,推荐1.8)Python(2或3都可以,linux自带py2,py3执行脚本会报错,需要修改脚本)ApacheMaven3.x(CompileDataX,如果下载的是官方的压缩包[datax.tar.gz],不用安装这个,如果是在git拉的项目,打包时需要)安装包编......