Skip to content

Commit f094ed3

Browse files
committed
feat: add solutions to lc problem: No.1206.Design Skiplist
1 parent ae484ea commit f094ed3

File tree

6 files changed

+723
-2
lines changed

6 files changed

+723
-2
lines changed

solution/1200-1299/1206.Design Skiplist/README.md

+243-1
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,264 @@ skiplist.search(1); // 返回 false,1 已被擦除
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
因为节点 `level` 随机,所以需要多个 `next` 指针,其余操作类似单链表
60+
5961
<!-- tabs:start -->
6062

6163
### **Python3**
6264

6365
<!-- 这里可写当前语言的特殊实现逻辑 -->
6466

6567
```python
66-
68+
class Node:
69+
def __init__(self, val: int, level: int):
70+
self.val = val
71+
self.next = [None for _ in range(level)]
72+
73+
74+
class Skiplist:
75+
max_level = 16
76+
p = 0.5
77+
78+
def __init__(self):
79+
self.head = Node(-1, self.max_level)
80+
self.level = 1
81+
82+
def search(self, target: int) -> bool:
83+
p = self.head
84+
for i in range(self.level - 1, -1, -1):
85+
p = self.find_closest(p, i, target)
86+
if p.next[i] != None and p.next[i].val == target:
87+
return True
88+
return False
89+
90+
def add(self, num: int) -> None:
91+
level = self.random_level()
92+
self.level = max(self.level, level)
93+
node = Node(num, level)
94+
p = self.head
95+
for i in range(self.level - 1, -1, -1):
96+
p = self.find_closest(p, i, num)
97+
if i < level:
98+
node.next[i] = p.next[i]
99+
p.next[i] = node
100+
101+
def erase(self, num: int) -> bool:
102+
ok = False
103+
p = self.head
104+
for i in range(self.level - 1, -1, -1):
105+
p = self.find_closest(p, i, num)
106+
if p.next[i] != None and p.next[i].val == num:
107+
p.next[i] = p.next[i].next[i]
108+
ok = True
109+
while self.level > 1 and self.head.next[self.level - 1] == None:
110+
self.level -= 1
111+
return ok
112+
113+
def find_closest(self, p: Node, level: int, target: int) -> Node:
114+
while p.next[level] != None and p.next[level].val < target:
115+
p = p.next[level]
116+
return p
117+
118+
def random_level(self) -> int:
119+
level = 1
120+
while level < self.max_level and random.random() < self.p:
121+
level += 1
122+
return level
123+
124+
125+
# Your Skiplist object will be instantiated and called as such:
126+
# obj = Skiplist()
127+
# param_1 = obj.search(target)
128+
# obj.add(num)
129+
# param_3 = obj.erase(num)
67130
```
68131

69132
### **Java**
70133

71134
<!-- 这里可写当前语言的特殊实现逻辑 -->
72135

73136
```java
137+
class Skiplist {
138+
139+
private static final int DEFAULT_MAX_LEVEL = 16;
140+
private static final double DEFAULT_P_FACTOR = 0.5;
141+
142+
private final Node head;
143+
private int currentLevel;
144+
145+
public Skiplist() {
146+
this.head = new Node(0, DEFAULT_MAX_LEVEL);
147+
this.currentLevel = 1;
148+
}
149+
150+
public boolean search(int target) {
151+
Node node = head;
152+
for (int i = currentLevel - 1; i >= 0; i--) {
153+
node = findClosest(node, i, target);
154+
if (node.next[i] != null && node.next[i].value == target) {
155+
return true;
156+
}
157+
}
158+
return false;
159+
}
160+
161+
public void add(int num) {
162+
int level = randomLevel();
163+
currentLevel = Math.max(currentLevel, level);
164+
Node newNode = new Node(num, level);
165+
Node updateNode = head;
166+
for (int i = currentLevel - 1; i >= 0; i--) {
167+
updateNode = findClosest(updateNode, i, num);
168+
if (i < level) {
169+
newNode.next[i] = updateNode.next[i];
170+
updateNode.next[i] = newNode;
171+
}
172+
}
173+
}
174+
175+
public boolean erase(int num) {
176+
boolean exist = false;
177+
Node node = head;
178+
for (int i = currentLevel - 1; i >= 0; i--) {
179+
node = findClosest(node, i, num);
180+
if (node.next[i] != null && node.next[i].value == num) {
181+
node.next[i] = node.next[i].next[i];
182+
exist = true;
183+
}
184+
}
185+
while (currentLevel > 1 && head.next[currentLevel - 1] == null) {
186+
currentLevel--;
187+
}
188+
return exist;
189+
}
190+
191+
private Node findClosest(Node node, int level, int value) {
192+
while (node.next[level] != null && node.next[level].value < value) {
193+
node = node.next[level];
194+
}
195+
return node;
196+
}
197+
198+
private int randomLevel() {
199+
int level = 1;
200+
while (level < DEFAULT_MAX_LEVEL && Math.random() < DEFAULT_P_FACTOR) {
201+
level++;
202+
}
203+
return level;
204+
}
205+
206+
static class Node {
207+
int value;
208+
Node[] next;
209+
210+
Node(int value, int level) {
211+
this.value = value;
212+
this.next = new Node[level];
213+
}
214+
}
215+
}
216+
```
74217

218+
### **Go**
219+
220+
```go
221+
func init() { rand.Seed(time.Now().UnixNano()) }
222+
223+
const (
224+
maxLevel = 16
225+
p = 0.5
226+
)
227+
228+
type node struct {
229+
val int
230+
next []*node
231+
}
232+
233+
func newNode(val, level int) *node {
234+
return &node{
235+
val: val,
236+
next: make([]*node, level),
237+
}
238+
}
239+
240+
type Skiplist struct {
241+
head *node
242+
level int
243+
}
244+
245+
func Constructor() Skiplist {
246+
return Skiplist{
247+
head: newNode(-1, maxLevel),
248+
level: 1,
249+
}
250+
}
251+
252+
func (this *Skiplist) Search(target int) bool {
253+
p := this.head
254+
for i := this.level - 1; i >= 0; i-- {
255+
p = findClosest(p, i, target)
256+
if p.next[i] != nil && p.next[i].val == target {
257+
return true
258+
}
259+
}
260+
return false
261+
}
262+
263+
func (this *Skiplist) Add(num int) {
264+
level := randomLevel()
265+
if level > this.level {
266+
this.level = level
267+
}
268+
node := newNode(num, level)
269+
p := this.head
270+
for i := this.level - 1; i >= 0; i-- {
271+
p = findClosest(p, i, num)
272+
if i < level {
273+
node.next[i] = p.next[i]
274+
p.next[i] = node
275+
}
276+
}
277+
}
278+
279+
func (this *Skiplist) Erase(num int) bool {
280+
ok := false
281+
p := this.head
282+
for i := this.level - 1; i >= 0; i-- {
283+
p = findClosest(p, i, num)
284+
if p.next[i] != nil && p.next[i].val == num {
285+
p.next[i] = p.next[i].next[i]
286+
ok = true
287+
}
288+
}
289+
for this.level > 1 && this.head.next[this.level-1] == nil {
290+
this.level--
291+
}
292+
return ok
293+
}
294+
295+
func findClosest(p *node, level, target int) *node {
296+
for p.next[level] != nil && p.next[level].val < target {
297+
p = p.next[level]
298+
}
299+
return p
300+
}
301+
302+
func randomLevel() int {
303+
level := 1
304+
for level < maxLevel && rand.Float64() < p {
305+
level++
306+
}
307+
return level
308+
}
309+
310+
/**
311+
* Your Skiplist object will be instantiated and called as such:
312+
* obj := Constructor();
313+
* param_1 := obj.Search(target);
314+
* obj.Add(num);
315+
* param_3 := obj.Erase(num);
316+
*/
75317
```
76318

77319
### **...**

0 commit comments

Comments
 (0)