文章目录
一、题目描述
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
输入: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 域的正确指向。
要攻克这个难点,我的方法分为四步:
- 首先,按照顺序,存储旧链表所有节点的 Random 字段(结构体指针数组 randomlist)。
- 在遍历旧链表节点的同时遍历 randomlist,将 randomlist 里存储的地址和当前链表节点的地址做对比,将 randomlist 里存储的地址转化为当前链表节点的序号,存入一个整型数组 index 。这个整型数组存储了每个节点的 Random 域指向了哪一个节点。
- 在创建新链表时,将每个节点的地址存入 new_randomlist 。
- 遍历新链,根据 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