首页 > 其他分享 >复杂链表的复制

复杂链表的复制

时间:2024-12-24 11:33:32浏览次数:4  
标签:Node cur nil 复杂 Next 链表 复制 节点

 

 

 

题意:需要对链表进行深拷贝,要同时拷贝链表节点的val、next指针和random指针
题解一:

逐个拷贝每个链表节点到当前节点的后面,分三次遍历,每次遍历走两步,最后达到深拷贝的目的
1、第一次遍历原链表,逐个拷贝当前节点的值和next执行,(1->2->3变成1->1'->2->2'->3->3'

2、第二次遍历链表,逐个拷贝当前节点的random指针

3、第三次遍历链表,拆分原节点和copy节点

 

时间复杂度:O(n)

空间复杂度:O(1)

func main() {
    node1 := &Node{Val: 1}
    node2 := &Node{Val: 2}
    node3 := &Node{Val: 3}

    node1.Next = node2
    node2.Next = node3
    node1.Random = node3 // Node 1's random points to Node 3
    node2.Random = node1 // Node 2's random points to Node 1
    node3.Random = nil
    copyNodeList(node1)
}
func copyNodeList(head *Node) *Node {
    if head == nil {
        return nil
    }

    // 1. 新生成copy节点放到原节点的后面,例如1->2->3这样的链表就变成了这样1->1'->2->2'->3->3'
    var cp *Node = nil
    for cur := head; cur != nil; cur = cur.Next.Next { // 因为是加上了copy节点,所以每次要移动2步
        cp = &Node{Val: cur.Val} // 此时拷贝节点的random指针都指向nil
        cp.Next = cur.Next
        cur.Next = cp
    }

    // 2. 随机指针的拷贝
    for cur := head; cur != nil; cur = cur.Next.Next {
        if cur.Random != nil { // random指针可能为空
            // cur.Next是cur的cp节点,所以cp节点的random指针是cur.random指针的cp节点,也就是cur.Random.Next
            cur.Next.Random = cur.Random.Next
        }
    }

    // 3. 拆分原节点 和 copy节点
    var temp *Node = nil
    newHead := head.Next
    for cur := head; cur != nil && cur.Next != nil; {
        temp = cur.Next      // copy节点
        cur.Next = temp.Next // 还原旧链表
        cur = temp           //拆分cp链表
    }
    //PrintList(head)
    //PrintList(newHead)
    return newHead
}

// PrintList 打印随机链表
func PrintList(head *Node) {
    cur := head
    var result [][]string
    for cur != nil {
        randomVal := "nil"
        if cur.Random != nil {
            randomVal = fmt.Sprintf("%d", cur.Random.Val)
        }

        result = append(result, []string{fmt.Sprintf("%d", cur.Val), randomVal})
        cur = cur.Next
    }
    fmt.Println(result)
}

 

链接:https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/solutions/994069/jian-zhi-offer-35-fu-za-lian-biao-de-fu-1iud0/

 

解法二:随机链表拷贝的难点,在于如何拷贝next指针和random指针,相当于要同时维护两条链表的关系,解法一是将两个指针的关系分开遍历处理,逐个拷贝;另一种解法就是使用哈希表(map[*node]*node),直接映射旧节点到新节点的拷贝关系,知道当前拷贝节点对应的旧节点状态,就可以通过找旧节点,然后赋值,实现深拷贝

属于空间换时间的解法
时间复杂度:O(n)
空间复杂度:O(n)

func copyRandomList(head *Node) *Node {
    if head == nil {
        return nil
    }
    // map中存的是(原节点->新节点)的映射关系,此时新节点只有val,指针并没有安排上
    nodeMap := make(map[*Node]*Node)
    for cur := head; cur != nil; cur = cur.Next {
        nodeMap[cur] = &Node{Val: cur.Val}
    }
    // 遍历原链表,根据map关系找到原节点状态,然后对拷贝节点进行赋值
    for cur := head; cur != nil; cur = cur.Next {
        nodeMap[cur].Next = nodeMap[cur.Next]
        nodeMap[cur].Random = nodeMap[cur.Random]
    }
    return nodeMap[head]
}

 

标签:Node,cur,nil,复杂,Next,链表,复制,节点
From: https://www.cnblogs.com/-citywall123/p/18627006

相关文章

  • MySQL主从复制中启用GTID(全局事务标识符)模式
    在MySQL中启用GTID(全局事务标识符)模式进行主从复制涉及几个步骤。GTID为每个事务赋予一个唯一的标识符,从而简化了复制过程和故障恢复。以下是启用GTID模式的基本步骤:首先确保两台数据库目前数据保持一致1.准备工作确保您使用的MySQL版本支持GTID。GTID从MySQL5.6版本开始支持......
  • Linux文件目录 --- 复制命令CP、递归复制目录、软连接、硬链接
    一、复制cp该命令用于复制文件或目录,下面是命令使用格式和常用的参数cp[参数]源文件或目录目标文件或目录                      #中间各有一个空格隔开参数作用-f覆盖同名文件或目录时不进行提醒-i          ......
  • 算法刷题Day7_翻转链表
    算法刷题Day7_单链表相关操作文章目录算法刷题Day7_单链表相关操作前言一、反转链表二、两两交换链表中的节点1.递归法2.迭代法总结前言提示:以下是本篇文章正文内容,下面案例可供参考一、反转链表classSolution{public:ListNode*reverseList(ListNode......
  • 算法刷题_删除链表的倒数第N个结点
    算法刷题Day8_删除链表的倒数第N个结点文章目录算法刷题Day8_删除链表的倒数第N个结点前言一、双指针思想二、具体步骤1.定义快慢指针2.fast指针先移动n+1步3.fast和slow一起移动4.删除倒数第N个节点三、完整代码总结前言一、双指针思想双指针的经典应用,如果......
  • 详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管
    目录详解js柯里化原理及用法,探究柯里化在ReduxSelector的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用一、什么是柯里化?1、原理解析2、一个直观的例子二、如何实现柯里化?1、底层实现2、工作原理解析3、测试我们的实现三、柯里化的优点1.参数复......
  • LRU 缓存(哈希表+双向链表)
    请你设计并实现一个满足  LRU(最近最少使用)缓存 约束的数据结构。实现 LRUCache 类:LRUCache(intcapacity) 以 正整数 作为容量 capacity 初始化LRU缓存intget(intkey) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。voidput(intkey,......
  • 合并 K 个升序链表(归并排序)
    给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一个有序链表中得到。1->1->2->3->4->......
  • TINYMCE编辑器从WORD复制粘贴公式
    编辑器:TinyMCE需求:复制粘贴word内容图片,图文混排,图片转存要求:开源,免费,技术支持前端:vue,vue2-cli,vue3-cli后端:java,jsp,springboot,asp.net,php,asp,.netcore,.netmvc,.netform平台:Windows,macOS,Linux,中标麒麟,银河麒麟,统信UOS,信创国产化CPU:x86(Intel,AMD,兆......
  • LeetCode《图解算法数据结构》链表:图书整理 I
    题目书店店员有一张链表形式的书单,每个节点代表一本书,节点中的值表示书的编号。为更方便整理书架,店员需要将书单倒过来排列,就可以从最后一本书开始整理,逐一将书放回到书架上。请倒序返回这个书单链表。输入head=[3,6,4,1]输出[1,4,6,3]解法1:递归classSolution{public......
  • 复制下来就能跑:Java实现图片转文字_Java 提取图片文字
    文章整体介绍本文教你如何用SpringAI给Java项目加上图片转文字的功能。传统上,我们用OCR技术来识别图片中的文字。现在有了大模型的帮助,我们可以更准确地理解图片内容。文章会一步步教你准备环境、配置API密钥和写代码的过程。使用的是springaialibaba和QWen千问的API。跑......