【LeetCode】剑指 Offer 35. 复杂链表的复制 – Go 语言题解

导读:本篇文章讲解 【LeetCode】剑指 Offer 35. 复杂链表的复制 – Go 语言题解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com


一、题目描述

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

在这里插入图片描述
示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

二、题目理解、解题思路

所谓复制一个链表,就是重新开辟一篇存储空间,在这片存储空间上,重新创建一个新链表,与原链表有同样的值和链接关系。其实就是 链表的深拷贝。想深入理解 golang 深浅拷贝的同学请移步:【Go】深拷贝与浅拷贝

其中,有同样的值很简单(Val 域),有同样的顺序关系也简单(Next 域)。

这个题的难点是实现新链表的 Random 域的正确指向。

要攻克这个难点,我的方法分为四步:

  1. 首先,按照顺序,存储旧链表所有节点的 Random 字段(结构体指针数组 randomlist)。
  2. 在遍历旧链表节点的同时遍历 randomlist,将 randomlist 里存储的地址和当前链表节点的地址做对比,将 randomlist 里存储的地址转化为当前链表节点的序号,存入一个整型数组 index 。这个整型数组存储了每个节点的 Random 域指向了哪一个节点。
  3. 在创建新链表时,将每个节点的地址存入 new_randomlist 。
  4. 遍历新链,根据 index 存储的旧链每个节点的 Random 指向哪个节点的信息,以及 new_randomlist 记录的新链每个节点的地址信息,给新链的每个节点的 Random 域赋值。

三、我的题解

Go 语言代码:

/**
 * Definition for a Node.
 * type Node struct {
 *     Val int
 *     Next *Node
 *     Random *Node
 * }
 */

func copyRandomList(Once *Node) *Node {
    if Once == nil{
        return nil
    }
    
    
    var randomlist []*Node     //记录原链表的所有Random字段
    var new_randomlist []*Node //记录新链的所有节点的地址
    
    
    //遍历链表,计算其长度k,并按顺序记录所有Random字段
    rancurr := Once
    k := 0
    for rancurr != nil{
        k ++
        randomlist = append(randomlist,rancurr.Random)
        rancurr = rancurr.Next
    }
    
    index := make([]int, k)     //记录k个节点的Random字段分别指向第几个节点


    var copy_newnode *Node

    //虚拟头结点
    copy_newnode = new(Node)
    head := copy_newnode
    curr := copy_newnode
    
    //创建新链表,并记录每个节点的Random字段分别指向第几个节点
    i := 0   //Once 的第几个节点
    for Once != nil{
        //寻找指向当前节点的其他节点,将其他节点的 index 项更改为当前节点的序号
        for j,d := range randomlist{
            if d == nil{
                index[j] = k
            }else if d == Once {
                index[j] = i
            }
        }
        
        //创建新节点
        copy_newnode = new(Node)
        copy_newnode.Val = Once.Val

        //将新节点的地址加入new_randomlist
        new_randomlist = append(new_randomlist,copy_newnode)
        
        curr.Next = copy_newnode
        curr = curr.Next

        Once = Once.Next
        i++
    }

    //遍历新链,根据 index 的记录和 new_randomlist 里的地址信息给新链所有节点的 Random 域赋值
    curr = head.Next
    for in := 0; in <(len(index)); in++{
        if index[in] == k{
            curr.Random = nil
        }else{
            curr.Random = new_randomlist[index[in]]
        } 
        curr = curr.Next
    }
   

    return head.Next

}

评判结果:
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118981.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!