mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-07 01:44:56 +08:00
Add solution 138 README
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
package leetcode
|
||||
|
||||
//执行用时:0 ms, 在所有 Go 提交中击败了100.00%的用户
|
||||
//内存消耗:3.4 MB, 在所有 Go 提交中击败了100.00%的用户
|
||||
// Node define
|
||||
type Node struct {
|
||||
Val int
|
||||
Next *Node
|
||||
@ -33,7 +32,6 @@ func copyNodeToLinkedList(head *Node) *Node {
|
||||
Next: cur.Next,
|
||||
}
|
||||
cur.Next, cur = node, cur.Next
|
||||
|
||||
}
|
||||
cur = head
|
||||
for cur != nil {
|
||||
|
@ -1,7 +1,115 @@
|
||||
package leetcode
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
type question138 struct {
|
||||
para138
|
||||
ans138
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para138 struct {
|
||||
head [][]int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans138 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem138(t *testing.T) {
|
||||
|
||||
qs := []question138{
|
||||
|
||||
{
|
||||
para138{[][]int{{7, structures.NULL}, {13, 0}, {11, 4}, {10, 2}, {1, 0}}},
|
||||
ans138{[][]int{{7, structures.NULL}, {13, 0}, {11, 4}, {10, 2}, {1, 0}}},
|
||||
},
|
||||
|
||||
{
|
||||
para138{[][]int{{1, 1}, {2, 1}}},
|
||||
ans138{[][]int{{1, 1}, {2, 1}}},
|
||||
},
|
||||
|
||||
{
|
||||
para138{[][]int{{3, structures.NULL}, {3, 0}, {3, structures.NULL}}},
|
||||
ans138{[][]int{{3, structures.NULL}, {3, 0}, {3, structures.NULL}}},
|
||||
},
|
||||
|
||||
{
|
||||
para138{[][]int{}},
|
||||
ans138{[][]int{}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 138------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans138, q.para138
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, node2Ints(copyRandomList(ints2Node(p.head))))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
||||
|
||||
func ints2Node(one [][]int) *Node {
|
||||
nodesMap := map[int]*Node{}
|
||||
for index, nodes := range one {
|
||||
tmp := &Node{Val: nodes[0]}
|
||||
nodesMap[index] = tmp
|
||||
}
|
||||
for index, node := range nodesMap {
|
||||
if index != len(one)-1 {
|
||||
node.Next = nodesMap[index+1]
|
||||
} else {
|
||||
node.Next = nil
|
||||
}
|
||||
}
|
||||
for index, nodes := range one {
|
||||
if nodes[1] == structures.NULL {
|
||||
nodesMap[index].Random = nil
|
||||
} else {
|
||||
nodesMap[index].Random = nodesMap[nodes[1]]
|
||||
}
|
||||
}
|
||||
return nodesMap[0]
|
||||
}
|
||||
|
||||
func node2Ints(head *Node) (res [][]int) {
|
||||
nodesMap, count, cur := map[*Node]int{}, 0, head
|
||||
if head == nil {
|
||||
return [][]int{}
|
||||
}
|
||||
for cur.Next != nil {
|
||||
nodesMap[cur] = count
|
||||
count++
|
||||
cur = cur.Next
|
||||
}
|
||||
nodesMap[cur] = count
|
||||
tmp := []int{}
|
||||
cur = head
|
||||
for cur.Next != nil {
|
||||
tmp := append(tmp, cur.Val)
|
||||
if cur.Random == nil {
|
||||
tmp = append(tmp, structures.NULL)
|
||||
} else {
|
||||
tmp = append(tmp, nodesMap[cur.Random])
|
||||
}
|
||||
res = append(res, tmp)
|
||||
cur = cur.Next
|
||||
}
|
||||
tmp = append(tmp, cur.Val)
|
||||
if cur.Random == nil {
|
||||
tmp = append(tmp, structures.NULL)
|
||||
} else {
|
||||
tmp = append(tmp, nodesMap[cur.Random])
|
||||
}
|
||||
res = append(res, tmp)
|
||||
return res
|
||||
}
|
||||
|
130
leetcode/0138.Copy-List-With-Random-Pointer/README.md
Normal file
130
leetcode/0138.Copy-List-With-Random-Pointer/README.md
Normal file
@ -0,0 +1,130 @@
|
||||
# [138. Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/)
|
||||
|
||||
## 题目
|
||||
|
||||
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
|
||||
|
||||
Return a **[deep copy](https://en.wikipedia.org/wiki/Object_copying#Deep_copy)** of the list.
|
||||
|
||||
The Linked List is represented in the input/output as a list of `n` nodes. Each node is represented as a pair of `[val, random_index]` where:
|
||||
|
||||
- `val`: an integer representing `Node.val`
|
||||
- `random_index`: the index of the node (range from `0` to `n-1`) where random pointer points to, or `null` if it does not point to any node.
|
||||
|
||||
**Example 1:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
|
||||
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
Input: head = [[1,1],[2,1]]
|
||||
Output: [[1,1],[2,1]]
|
||||
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
Input: head = [[3,null],[3,0],[3,null]]
|
||||
Output: [[3,null],[3,0],[3,null]]
|
||||
|
||||
```
|
||||
|
||||
**Example 4:**
|
||||
|
||||
```
|
||||
Input: head = []
|
||||
Output: []
|
||||
Explanation: Given linked list is empty (null pointer), so return null.
|
||||
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `10000 <= Node.val <= 10000`
|
||||
- `Node.random` is null or pointing to a node in the linked list.
|
||||
- The number of nodes will not exceed 1000.
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。
|
||||
|
||||
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
|
||||
|
||||
- val:一个表示 Node.val 的整数。
|
||||
- random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 这道题严格意义上是数据结构题,根据给定的数据结构,对它进行深拷贝。
|
||||
- 先将每个节点都复制一份,放在它的 next 节点中。如此穿插的复制一份链表。
|
||||
|
||||

|
||||
|
||||
再将穿插版的链表的 random 指针指向正确的位置。
|
||||
|
||||

|
||||
|
||||
再将穿插版的链表的 next 指针指向正确的位置。最后分开这交织在一起的两个链表的头节点,即可分开 2 个链表。
|
||||
|
||||

|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
// Node define
|
||||
type Node struct {
|
||||
Val int
|
||||
Next *Node
|
||||
Random *Node
|
||||
}
|
||||
|
||||
func copyRandomList(head *Node) *Node {
|
||||
if head == nil {
|
||||
return nil
|
||||
}
|
||||
tempHead := copyNodeToLinkedList(head)
|
||||
return splitLinkedList(tempHead)
|
||||
}
|
||||
|
||||
func splitLinkedList(head *Node) *Node {
|
||||
cur := head
|
||||
head = head.Next
|
||||
for cur != nil && cur.Next != nil {
|
||||
cur.Next, cur = cur.Next.Next, cur.Next
|
||||
}
|
||||
return head
|
||||
}
|
||||
|
||||
func copyNodeToLinkedList(head *Node) *Node {
|
||||
cur := head
|
||||
for cur != nil {
|
||||
node := &Node{
|
||||
Val: cur.Val,
|
||||
Next: cur.Next,
|
||||
}
|
||||
cur.Next, cur = node, cur.Next
|
||||
}
|
||||
cur = head
|
||||
for cur != nil {
|
||||
if cur.Random != nil {
|
||||
cur.Next.Random = cur.Random.Next
|
||||
}
|
||||
cur = cur.Next.Next
|
||||
}
|
||||
return head
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user