#1206
Design Skiplist
HardLinked ListDesignLinked ListRandomized Algorithms
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n²) | O(log n) |
| Space | O(1) | O(n) |
💡
Intuition
Time O(log n)Space O(n)
The optimal approach uses multiple layers of linked lists to create a Skiplist, allowing us to skip over many elements, which reduces the time complexity of search, add, and erase operations to O(log n). This is similar to how you might skip steps when climbing a staircase.
⚙️
Algorithm
4 steps- 1Step 1: Create a Skiplist with multiple levels, where each level is a sorted linked list.
- 2Step 2: For search, start from the topmost level and move downwards, skipping nodes as necessary until you find the target or reach the bottom.
- 3Step 3: For add, randomly decide the level of the new node and insert it into each level accordingly.
- 4Step 4: For erase, locate the node in all levels and remove it.
solution.py53 lines
1# Full working Python code
2import random
3
4class Node:
5 def __init__(self, value, level):
6 self.value = value
7 self.forward = [None] * (level + 1)
8
9class Skiplist:
10 def __init__(self):
11 self.max_level = 16
12 self.header = Node(-1, self.max_level)
13 self.level = 0
14
15 def random_level(self):
16 level = 0
17 while random.random() < 0.5 and level < self.max_level:
18 level += 1
19 return level
20
21 def search(self, target):
22 current = self.header
23 for i in range(self.level, -1, -1):
24 while current.forward[i] and current.forward[i].value < target:
25 current = current.forward[i]
26 current = current.forward[0]
27 return current is not None and current.value == target
28
29 def add(self, num):
30 new_level = self.random_level()
31 if new_level > self.level:
32 for i in range(self.level + 1, new_level + 1):
33 self.header.forward[i] = None
34 self.level = new_level
35 new_node = Node(num, new_level)
36 current = self.header
37 for i in range(self.level, -1, -1):
38 while current.forward[i] and current.forward[i].value < num:
39 current = current.forward[i]
40 if i <= new_level:
41 new_node.forward[i] = current.forward[i]
42 current.forward[i] = new_node
43
44 def erase(self, num):
45 current = self.header
46 found = False
47 for i in range(self.level, -1, -1):
48 while current.forward[i] and current.forward[i].value < num:
49 current = current.forward[i]
50 if current.forward[i] and current.forward[i].value == num:
51 found = True
52 current.forward[i] = current.forward[i].forward[i]
53 return foundℹ
Complexity note: The time complexity is O(log n) because we can skip many nodes in each operation, effectively reducing the number of comparisons needed.
- 1Skiplist allows for efficient search, add, and erase operations by using multiple layers.
- 2Randomly determining the level of nodes helps maintain balance, similar to how trees balance themselves.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.