Skip to content

Commit 2e70e52

Browse files
committed
feat: 138. Copy List with Random Pointer
1 parent 0dea515 commit 2e70e52

File tree

3 files changed

+231
-0
lines changed

3 files changed

+231
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
title: 138. Copy List with Random Pointer
3+
subtitle: "https://leetcode.com/problems/copy-list-with-random-pointer/description/"
4+
date: 2024-03-12T22:30:00+08:00
5+
lastmod: 2024-03-12T22:30:00+08:00
6+
draft: false
7+
author: "Kimi.Tsai"
8+
authorLink: "https://kimi0230.github.io/"
9+
description: "0138.Copy-List-with-Random-Pointer"
10+
license: ""
11+
images: []
12+
13+
tags: [LeetCode, Go, Medium, Copy List with Random Pointer, Facebook ,Amazon ,Microsoft ,Bloomberg ,Google]
14+
categories: [LeetCode]
15+
16+
featuredImage: ""
17+
featuredImagePreview: ""
18+
19+
hiddenFromHomePage: false
20+
hiddenFromSearch: false
21+
twemoji: false
22+
lightgallery: true
23+
ruby: true
24+
fraction: true
25+
fontawesome: true
26+
linkToMarkdown: false
27+
rssFullText: false
28+
29+
toc:
30+
enable: true
31+
auto: true
32+
code:
33+
copy: true
34+
maxShownLines: 200
35+
math:
36+
enable: false
37+
# ...
38+
mapbox:
39+
# ...
40+
share:
41+
enable: true
42+
# ...
43+
comment:
44+
enable: true
45+
# ...
46+
library:
47+
css:
48+
# someCSS = "some.css"
49+
# located in "assets/"
50+
# Or
51+
# someCSS = "https://cdn.example.com/some.css"
52+
js:
53+
# someJS = "some.js"
54+
# located in "assets/"
55+
# Or
56+
# someJS = "https://cdn.example.com/some.js"
57+
seo:
58+
images: []
59+
# ...
60+
---
61+
# [138. Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/)
62+
63+
## 題目
64+
65+
## 題目大意
66+
67+
68+
## 解題思路
69+
對於數據結構複製,甭管他怎麼變,你就記住最簡單的方式:一個哈希表 + 兩次遍歷
70+
* 第一次遍歷專門clone節點,藉助 Hash表把原始節點和clone節點的映射存儲起來;
71+
* 第二次專門組裝節點,照著原數據結構的樣子,把clone節點的指標組裝起來。
72+
73+
## Big O
74+
75+
* 時間複雜 : `O(n)` ,其中 n 是鏈表的長度。 對於每個節點,我們至多訪問其「後繼節點」和「隨機指標指向的節點」各一次,均攤每個點至多被訪問兩次。
76+
* 空間複雜 : `O(n)` 其中 n 是鏈表的長度。 為哈希表的空間開銷
77+
78+
## 來源
79+
* https://leetcode.com/problems/copy-list-with-random-pointer/description/
80+
* https://leetcode.cn/problems/
81+
82+
## 解答
83+
https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0138.Copy-List-with-Random-Pointer/main.go
84+
85+
```go
86+
package copylistwithrandompointer
87+
88+
/**
89+
* Definition for a Node.
90+
* type Node struct {
91+
* Val int
92+
* Next *Node
93+
* Random *Node
94+
* }
95+
*/
96+
97+
var cacheMap map[*Node]*Node
98+
99+
// 時間複雜 O(n), 空間複雜 O(n)
100+
func copyRandomList(head *Node) *Node {
101+
cacheMap = make(map[*Node]*Node)
102+
return deepCopy(head)
103+
}
104+
105+
func deepCopy(node *Node) *Node {
106+
if node == nil {
107+
return nil
108+
}
109+
if n, ok := cacheMap[node]; ok {
110+
return n
111+
}
112+
newNode := &Node{Val: node.Val}
113+
cacheMap[node] = newNode
114+
newNode.Next = deepCopy(node.Next)
115+
newNode.Random = deepCopy(node.Random)
116+
return newNode
117+
}
118+
119+
func copyRandomList2(head *Node) *Node {
120+
cMap := make(map[*Node]*Node)
121+
cur := head
122+
// 第一次遍歷專門clone節點,藉助 Hash表把原始節點和clone節點的映射存儲起來;
123+
for cur != nil {
124+
newNode := &Node{Val: cur.Val}
125+
cMap[cur] = newNode
126+
cur = cur.Next
127+
}
128+
// 第二次專門組裝節點,照著原數據結構的樣子,把clone節點的指標組裝起來。
129+
newHead := cMap[head]
130+
for head != nil {
131+
node := cMap[head]
132+
node.Next = cMap[head.Next]
133+
node.Random = cMap[head.Random]
134+
head = head.Next
135+
}
136+
return newHead
137+
}
138+
139+
```
140+
141+
## Benchmark
142+
143+
```sh
144+
145+
```
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package copylistwithrandompointer
2+
3+
/**
4+
* Definition for a Node.
5+
* type Node struct {
6+
* Val int
7+
* Next *Node
8+
* Random *Node
9+
* }
10+
*/
11+
12+
var cacheMap map[*Node]*Node
13+
14+
// 時間複雜 O(n), 空間複雜 O(n)
15+
func copyRandomList(head *Node) *Node {
16+
cacheMap = make(map[*Node]*Node)
17+
return deepCopy(head)
18+
}
19+
20+
func deepCopy(node *Node) *Node {
21+
if node == nil {
22+
return nil
23+
}
24+
if n, ok := cacheMap[node]; ok {
25+
return n
26+
}
27+
newNode := &Node{Val: node.Val}
28+
cacheMap[node] = newNode
29+
newNode.Next = deepCopy(node.Next)
30+
newNode.Random = deepCopy(node.Random)
31+
return newNode
32+
}
33+
34+
func copyRandomList2(head *Node) *Node {
35+
cMap := make(map[*Node]*Node)
36+
cur := head
37+
// 第一次遍歷專門clone節點,藉助 Hash表把原始節點和clone節點的映射存儲起來;
38+
for cur != nil {
39+
newNode := &Node{Val: cur.Val}
40+
cMap[cur] = newNode
41+
cur = cur.Next
42+
}
43+
// 第二次專門組裝節點,照著原數據結構的樣子,把clone節點的指標組裝起來。
44+
newHead := cMap[head]
45+
for head != nil {
46+
node := cMap[head]
47+
node.Next = cMap[head.Next]
48+
node.Random = cMap[head.Random]
49+
head = head.Next
50+
}
51+
return newHead
52+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package
2+
3+
import "testing"
4+
5+
var tests = []struct {
6+
arg1 string
7+
want int
8+
}{
9+
{
10+
"bbbab",
11+
4,
12+
},
13+
}
14+
15+
func TestLongestPalindromeSubseq(t *testing.T) {
16+
for _, tt := range tests {
17+
// if got := ReverseList(tt.arg1); !reflect.DeepEqual(got, tt.want) {
18+
if got := LongestPalindromeSubseq(tt.arg1); got != tt.want {
19+
t.Errorf("got = %v, want = %v", got, tt.want)
20+
}
21+
}
22+
}
23+
24+
func BenchmarkLongestPalindromeSubseq(b *testing.B) {
25+
b.ResetTimer()
26+
for i := 0; i < b.N; i++ {
27+
LongestPalindromeSubseq(tests[0].arg1)
28+
}
29+
}
30+
31+
/*
32+
go test -benchmem -run=none LeetcodeGolang/Leetcode/0354.Russian-Doll-Envelopes -bench=.
33+
34+
*/

0 commit comments

Comments
 (0)