本文最后更新于 2025-03-30T12:48:08+08:00
题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| 不使用任何库函数,设计一个跳表。
跳表是在 O(log(n)) 时间内完成增加、删除、搜索操作的数据结构。
跳表相比于树堆与红黑树,其功能与性能相当,并且跳表的代码长度相较下更短,其设计思想与链表相似。
例如,一个跳表包含 [30, 40, 50, 60, 70, 90],然后增加 80、45 到跳表中,以下图的方式操作:
跳表中有很多层,每一层是一个短的链表。
在第一层的作用下,增加、删除和搜索操作的时间复杂度不超过 O(n)。
跳表的每一个操作的平均时间复杂度是 O(log(n)),空间复杂度是 O(n)。
在本题中,你的设计应该要包含这些函数:
bool search(int target) : 返回target是否存在于跳表中。
void add(int num): 插入一个元素到跳表。
bool erase(int num): 在跳表中删除一个值,如果 num 不存在,直接返回 false.
如果存在多个 num ,删除其中任意一个即可。
了解更多 : https://en.wikipedia.org/wiki/Skip_list
注意,跳表中可能存在多个相同的值,你的代码需要处理这种情况。
样例:
Skiplist skiplist = new Skiplist();
skiplist.add(1); skiplist.add(2); skiplist.add(3); skiplist.search(0); skiplist.add(4); skiplist.search(1); skiplist.erase(0); skiplist.erase(1); skiplist.search(1); 约束条件:
0 <= num, target <= 20000 最多调用 50000 次 search, add, 以及 erase操作。
|
题目思路
- 1、没啥时间重新写一个vector,现在偷点懒用一下vector的库函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| struct Node { int key; vector<Node*> nexts; Node(int level,int k) : nexts(level + 1),key(k) {}; };
class Skiplist { private: Node* head; int allLevel = -1; public: Skiplist() { head = new Node(31,-1); } bool search(int key) { Node* cur = head; for(int curLevel = allLevel; curLevel >= 0; curLevel--) { while(cur -> nexts[curLevel] && cur -> nexts[curLevel] -> key < key) { cur = cur -> nexts[curLevel]; } if(cur -> nexts[curLevel] && cur -> nexts[curLevel] -> key == key) return true; } return false; } void add(int key) { int newLevel = getLevel(); allLevel = max(allLevel, newLevel); Node* cur = head; Node* newNode = new Node(newLevel, key); for(int curLevel = allLevel; curLevel >= 0; curLevel--) { while(cur -> nexts[curLevel] && cur -> nexts[curLevel] -> key < key){ cur = cur -> nexts[curLevel]; } if(curLevel <= newLevel) { newNode -> nexts[curLevel] = cur -> nexts[curLevel]; cur -> nexts[curLevel] = newNode; } } } bool erase(int key) { Node* cur = head; bool flag = false; for(int curLevel = allLevel; curLevel >= 0; curLevel--) { while(cur -> nexts[curLevel] && cur -> nexts[curLevel] -> key < key) { cur = cur -> nexts[curLevel]; } if(cur -> nexts[curLevel] && cur -> nexts[curLevel] -> key == key) { flag = true; Node* tmp = cur -> nexts[curLevel] -> nexts[curLevel]; cur -> nexts[curLevel] -> nexts[curLevel] = nullptr; cur -> nexts[curLevel] = tmp; } } if(flag == false) return false; return true; } int getLevel() { int ans = 0; while(ans < 32 && rand() < RAND_MAX * 0.25) ans++; return ans; } };
|
复杂度
- 时间复杂度:O(nlogn)
- 空间复杂度:O(n ^ 2)
Day 91 1206. 设计跳表
https://chaggle.github.io/2021/12/09/Leetcode/91-day/day-91/