Skip to content

Commit a430d33

Browse files
committed
feat: add solutions to lc problem: No.1206
No.1206.Design Skiplist
1 parent 65783cd commit a430d33

File tree

5 files changed

+508
-235
lines changed

5 files changed

+508
-235
lines changed

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

+173-79
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ skiplist.search(1); // 返回 false,1 已被擦除
6666

6767
<!-- 这里可写通用的实现逻辑 -->
6868

69-
因为节点 `level` 随机,所以需要多个 `next` 指针,其余操作类似单链表
69+
**方法一:数据结构**
70+
71+
因为节点 `level` 随机,所以需要多个 `next` 指针,其余操作类似单链表。
7072

7173
<!-- tabs:start -->
7274

@@ -76,54 +78,56 @@ skiplist.search(1); // 返回 false,1 已被擦除
7678

7779
```python
7880
class Node:
81+
__slots__ = ['val', 'next']
82+
7983
def __init__(self, val: int, level: int):
8084
self.val = val
81-
self.next = [None for _ in range(level)]
85+
self.next = [None] * level
8286

8387

8488
class Skiplist:
85-
max_level = 16
86-
p = 0.5
89+
max_level = 32
90+
p = 0.25
8791

8892
def __init__(self):
8993
self.head = Node(-1, self.max_level)
90-
self.level = 1
94+
self.level = 0
9195

9296
def search(self, target: int) -> bool:
93-
p = self.head
97+
curr = self.head
9498
for i in range(self.level - 1, -1, -1):
95-
p = self.find_closest(p, i, target)
96-
if p.next[i] != None and p.next[i].val == target:
99+
curr = self.find_closest(curr, i, target)
100+
if curr.next[i] and curr.next[i].val == target:
97101
return True
98102
return False
99103

100104
def add(self, num: int) -> None:
105+
curr = self.head
101106
level = self.random_level()
102-
self.level = max(self.level, level)
103107
node = Node(num, level)
104-
p = self.head
108+
self.level = max(self.level, level)
105109
for i in range(self.level - 1, -1, -1):
106-
p = self.find_closest(p, i, num)
110+
curr = self.find_closest(curr, i, num)
107111
if i < level:
108-
node.next[i] = p.next[i]
109-
p.next[i] = node
112+
node.next[i] = curr.next[i]
113+
curr.next[i] = node
110114

111115
def erase(self, num: int) -> bool:
116+
curr = self.head
112117
ok = False
113-
p = self.head
114118
for i in range(self.level - 1, -1, -1):
115-
p = self.find_closest(p, i, num)
116-
if p.next[i] != None and p.next[i].val == num:
117-
p.next[i] = p.next[i].next[i]
119+
curr = self.find_closest(curr, i, num)
120+
if curr.next[i] and curr.next[i].val == num:
121+
curr.next[i] = curr.next[i].next[i]
118122
ok = True
119-
while self.level > 1 and self.head.next[self.level - 1] == None:
123+
while self.level > 1 and self.head.next[self.level - 1] is None:
120124
self.level -= 1
121125
return ok
122126

123-
def find_closest(self, p: Node, level: int, target: int) -> Node:
124-
while p.next[level] != None and p.next[level].val < target:
125-
p = p.next[level]
126-
return p
127+
def find_closest(self, curr: Node, level: int, target: int) -> Node:
128+
while curr.next[level] and curr.next[level].val < target:
129+
curr = curr.next[level]
130+
return curr
127131

128132
def random_level(self) -> int:
129133
level = 1
@@ -145,84 +149,90 @@ class Skiplist:
145149

146150
```java
147151
class Skiplist {
148-
149-
private static final int DEFAULT_MAX_LEVEL = 16;
150-
private static final double DEFAULT_P_FACTOR = 0.5;
151-
152-
private final Node head;
153-
private int currentLevel;
152+
private static final int MAX_LEVEL = 32;
153+
private static final double P = 0.25;
154+
private static final Random RANDOM = new Random();
155+
private final Node head = new Node(-1, MAX_LEVEL);
156+
private int level = 0;
154157

155158
public Skiplist() {
156-
this.head = new Node(0, DEFAULT_MAX_LEVEL);
157-
this.currentLevel = 1;
159+
158160
}
159161

160162
public boolean search(int target) {
161-
Node node = head;
162-
for (int i = currentLevel - 1; i >= 0; i--) {
163-
node = findClosest(node, i, target);
164-
if (node.next[i] != null && node.next[i].value == target) {
165-
return true;
166-
}
167-
}
168-
return false;
163+
Node curr = head;
164+
for (int i = level - 1; i >= 0; --i) {
165+
curr = findClosest(curr, i, target);
166+
if (curr.next[i] != null && curr.next[i].val == target) {
167+
return true;
168+
}
169+
}
170+
return false;
169171
}
170172

171173
public void add(int num) {
172-
int level = randomLevel();
173-
currentLevel = Math.max(currentLevel, level);
174-
Node newNode = new Node(num, level);
175-
Node updateNode = head;
176-
for (int i = currentLevel - 1; i >= 0; i--) {
177-
updateNode = findClosest(updateNode, i, num);
178-
if (i < level) {
179-
newNode.next[i] = updateNode.next[i];
180-
updateNode.next[i] = newNode;
181-
}
182-
}
174+
Node curr = head;
175+
int lv = randomLevel();
176+
Node node = new Node(num, lv);
177+
level = Math.max(level, lv);
178+
for (int i = level - 1; i >= 0; --i) {
179+
curr = findClosest(curr, i, num);
180+
if (i < lv) {
181+
node.next[i] = curr.next[i];
182+
curr.next[i] = node;
183+
}
184+
}
183185
}
184186

185187
public boolean erase(int num) {
186-
boolean exist = false;
187-
Node node = head;
188-
for (int i = currentLevel - 1; i >= 0; i--) {
189-
node = findClosest(node, i, num);
190-
if (node.next[i] != null && node.next[i].value == num) {
191-
node.next[i] = node.next[i].next[i];
192-
exist = true;
193-
}
194-
}
195-
while (currentLevel > 1 && head.next[currentLevel - 1] == null) {
196-
currentLevel--;
197-
}
198-
return exist;
188+
Node curr = head;
189+
boolean ok = false;
190+
for (int i = level - 1; i >= 0; --i) {
191+
curr = findClosest(curr, i, num);
192+
if (curr.next[i] != null && curr.next[i].val == num) {
193+
curr.next[i] = curr.next[i].next[i];
194+
ok = true;
195+
}
196+
}
197+
while (level > 1 && head.next[level - 1] == null) {
198+
--level;
199+
}
200+
return ok;
199201
}
200202

201-
private Node findClosest(Node node, int level, int value) {
202-
while (node.next[level] != null && node.next[level].value < value) {
203-
node = node.next[level];
204-
}
205-
return node;
203+
private Node findClosest(Node curr, int level, int target) {
204+
while (curr.next[level] != null && curr.next[level].val < target) {
205+
curr = curr.next[level];
206+
}
207+
return curr;
206208
}
207209

208-
private int randomLevel() {
209-
int level = 1;
210-
while (level < DEFAULT_MAX_LEVEL && Math.random() < DEFAULT_P_FACTOR) {
211-
level++;
212-
}
213-
return level;
210+
private static int randomLevel() {
211+
int level = 1;
212+
while (level < MAX_LEVEL && RANDOM.nextDouble() < P) {
213+
++level;
214+
}
215+
return level;
214216
}
215217

216218
static class Node {
217-
int value;
218-
Node[] next;
219+
int val;
220+
Node[] next;
219221

220-
Node(int value, int level) {
221-
this.value = value;
222-
this.next = new Node[level];
223-
}
222+
Node(int val, int level) {
223+
this.val = val;
224+
next = new Node[level];
225+
}
224226
}
225227
}
228+
229+
/**
230+
* Your Skiplist object will be instantiated and called as such:
231+
* Skiplist obj = new Skiplist();
232+
* boolean param_1 = obj.search(target);
233+
* obj.add(num);
234+
* boolean param_3 = obj.erase(num);
235+
*/
226236
```
227237

228238
### **Go**
@@ -326,6 +336,90 @@ func randomLevel() int {
326336
*/
327337
```
328338

339+
### **C++**
340+
341+
```cpp
342+
struct Node {
343+
int val;
344+
vector<Node*> next;
345+
Node(int v, int level) : val(v), next(level, nullptr) {}
346+
};
347+
348+
class Skiplist {
349+
public:
350+
const int p = RAND_MAX / 4;
351+
const int maxLevel = 32;
352+
Node* head;
353+
int level;
354+
355+
Skiplist() {
356+
head = new Node(-1, maxLevel);
357+
level = 0;
358+
}
359+
360+
bool search(int target) {
361+
Node* curr = head;
362+
for (int i = level - 1; ~i; --i)
363+
{
364+
curr = findClosest(curr, i, target);
365+
if (curr->next[i] && curr->next[i]->val == target) return true;
366+
}
367+
return false;
368+
}
369+
370+
void add(int num) {
371+
Node* curr = head;
372+
int lv = randomLevel();
373+
Node* node = new Node(num, lv);
374+
level = max(level, lv);
375+
for (int i = level - 1; ~i; --i)
376+
{
377+
curr = findClosest(curr, i, num);
378+
if (i < lv)
379+
{
380+
node->next[i] = curr->next[i];
381+
curr->next[i] = node;
382+
}
383+
}
384+
}
385+
386+
bool erase(int num) {
387+
Node* curr = head;
388+
bool ok = false;
389+
for (int i = level - 1; ~i; --i)
390+
{
391+
curr = findClosest(curr, i, num);
392+
if (curr->next[i] && curr->next[i]->val == num)
393+
{
394+
curr->next[i] = curr->next[i]->next[i];
395+
ok = true;
396+
}
397+
}
398+
while (level > 1 && !head->next[level - 1]) --level;
399+
return ok;
400+
}
401+
402+
Node* findClosest(Node* curr, int level, int target) {
403+
while (curr->next[level] && curr->next[level]->val < target) curr = curr->next[level];
404+
return curr;
405+
}
406+
407+
int randomLevel() {
408+
int lv = 1;
409+
while (lv < maxLevel && rand() < p) ++lv;
410+
return lv;
411+
}
412+
};
413+
414+
/**
415+
* Your Skiplist object will be instantiated and called as such:
416+
* Skiplist* obj = new Skiplist();
417+
* bool param_1 = obj->search(target);
418+
* obj->add(num);
419+
* bool param_3 = obj->erase(num);
420+
*/
421+
```
422+
329423
### **...**
330424
331425
```

0 commit comments

Comments
 (0)