当前位置:网站首页>[1206. Design skip table]
[1206. Design skip table]
2022-07-27 03:22:00 【[email protected]】
source : Power button (LeetCode)
describe :
Do not use any library functions , To design a Jump watch .
The data structure of jump table is composed of William Pugh Invented , For a detailed introduction of the skip table, please refer to the paper : Skip Lists: A Probabilistic Alternative to Balanced Trees
Jump watch Is in O(log(n)) Add... In time 、 Delete 、 The data structure of the search operation . Compared with tree pile and red black tree , Its function and performance are equivalent , And the code length of the jump table is shorter , Its design idea is similar to the linked list .
for example , A jump table contains [30, 40, 50, 60, 70, 90] , Then increase 80、45 To jump table , Operate as shown in the following figure :

There are many layers in the jump table , Each layer is a short linked list . Under the action of the first layer , increase 、 The time complexity of deletion and search operations does not exceed O(n). The average time complexity of each operation of the jump table is O(log(n)), The space complexity is O(n).
In the subject , Your design should include these functions :
bool search(int target): returntargetWhether it exists in the jump table .void add(int num): Insert an element into the jump table .bool erase(int num): Delete a value in the jump table , Ifnumnon-existent , Go straight back to false. If there are multiplenum, Any one of them can be deleted .
Be careful , There may be multiple identical values in the jump table , Your code needs to handle this situation .
Example 1:
Input
["Skiplist", "add", "add", "add", "search", "add", "search", "erase", "erase", "search"]
[[], [1], [2], [3], [0], [4], [1], [0], [1], [1]]
Output
[null, null, null, null, false, null, true, false, true, false]
explain
Skiplist skiplist = new Skiplist();
skiplist.add(1);
skiplist.add(2);
skiplist.add(3);
skiplist.search(0); // return false
skiplist.add(4);
skiplist.search(1); // return true
skiplist.erase(0); // return false,0 Not in the jump table
skiplist.erase(1); // return true
skiplist.search(1); // return false,1 Has been erased
Tips :
0 <= num, target <= 2 * 104
call search, add, erase The number of operations shall not be greater than 5 * 104
Method : Direct structure
Jump table is a kind of randomized data structure , It can be regarded as a variety of binary tree , It's in performance with the red black tree 、 AVL A tree is equal to a tree , But the principle of meter jumping is very simple , Currently in Redis and LevelDB All of them are useful for . The expected space complexity of the jump table is O(n), Jump table query , The expected time complexity of the insert and delete operations is O(logn). The jump table is actually a multi-layer ordered linked list , Each layer of the jump list is an ordered linked list , And satisfy that each is located in i The nodes of the layer are pp The probability of appearing in the second i + 1 layer , among p Constant .
Its structure is similar to that shown in the figure below :
Jump table when searching , First, from the current top L(n) Layer starts to look up , Compare one by one at the current level until the next node of the current node is greater than or equal to the target node , Then move to the next level to find , Repeat this process until you reach the first floor . here , If the next node is the target node , Then the search is successful ; conversely , Then the element does not exist . Since you start searching from the top to the bottom , Because the elements appearing at the lower level may not appear at the higher level , Therefore, the skip table will skip some elements in the process of searching , Compared with the query of ordered linked list , The query speed of jump table will be faster .
Jump table initialization 、 lookup 、 add to 、 The deletion operation is described in detail as follows :

- search: The current maximum number of layers from the jump table level Layer starts to look up , Compare one by one at the current level until the next node of the current node is greater than or equal to the target node , Then move to the next level to find , Repeat this process until you reach the 1 layer . here , Ruodi 1 The value of the next node of the layer is equal to target, Then return to true; conversely , Then return to false. As shown in the figure :

- add: The current maximum number of layers from the jump table level Layer starts to look up , Compare one by one at the current level until the next node of the current node is greater than or equal to the target node , Then move to the next level to find , Repeat this process until you reach the 1 layer . Set the newly added node as newNode, We need to calculate the number of layers of nodes inserted this time lv, If level Less than lv, It also needs to be updated level. We use arrays update Save the last node found in each layer , The first i The last node of the layer is update[i]. We will newNode The subsequent nodes of point to update[i] The next node of , Simultaneous updating update[i] The subsequent nodes are newNode. As shown in the figure :





- erase: First, we need to find out whether the current element exists in the jump table . The current maximum number of layers from the jump table level Layer starts to look up , Compare one by one at the current level until the next node of the current node is greater than or equal to the target node , Then move to the next level to find , Repeat this process until you reach the 1 layer . If the first 1 The next node of the layer is not equal to num when , It means that the current element does not exist and returns directly . We use arrays update Save the last node found in each layer , The first i The last node of the layer is update[i]. At this time i The value of the next node of the layer is num, Then we need to delete it from the jump table . Due to the first i Layer with p The probability of appearing in the second i + 1 layer , Therefore, we should start from 1 The layer starts to update up , take num from update[i] Delete in the next jump of , Simultaneous updating update[i] Subsequent node , Until the linked list of the current layer does not appear num The node of . Finally, we need to update the current maximum number of layers in the jump table level. As shown in the figure :






Code :
constexpr int MAX_LEVEL = 32;
constexpr double P_FACTOR = 0.25;
struct SkiplistNode {
int val;
vector<SkiplistNode *> forward;
SkiplistNode(int _val, int _maxLevel = MAX_LEVEL) : val(_val), forward(_maxLevel, nullptr) {
}
};
class Skiplist {
private:
SkiplistNode * head;
int level;
mt19937 gen{
random_device{
}()};
uniform_real_distribution<double> dis;
public:
Skiplist(): head(new SkiplistNode(-1)), level(0), dis(0, 1) {
}
bool search(int target) {
SkiplistNode *curr = this->head;
for (int i = level - 1; i >= 0; i--) {
/* Find No i The layer is smaller than and closest to target The elements of */
while (curr->forward[i] && curr->forward[i]->val < target) {
curr = curr->forward[i];
}
}
curr = curr->forward[0];
/* Detect whether the value of the current element is equal to target */
if (curr && curr->val == target) {
return true;
}
return false;
}
void add(int num) {
vector<SkiplistNode *> update(MAX_LEVEL, head);
SkiplistNode *curr = this->head;
for (int i = level - 1; i >= 0; i--) {
/* Find No i The layer is smaller than and closest to num The elements of */
while (curr->forward[i] && curr->forward[i]->val < num) {
curr = curr->forward[i];
}
update[i] = curr;
}
int lv = randomLevel();
level = max(level, lv);
SkiplistNode *newNode = new SkiplistNode(num, lv);
for (int i = 0; i < lv; i++) {
/* Right. i Update the status of the layer , Change the current element's forward Point to new node */
newNode->forward[i] = update[i]->forward[i];
update[i]->forward[i] = newNode;
}
}
bool erase(int num) {
vector<SkiplistNode *> update(MAX_LEVEL, nullptr);
SkiplistNode *curr = this->head;
for (int i = level - 1; i >= 0; i--) {
/* Find No i The layer is smaller than and closest to num The elements of */
while (curr->forward[i] && curr->forward[i]->val < num) {
curr = curr->forward[i];
}
update[i] = curr;
}
curr = curr->forward[0];
/* If the value does not exist, it returns false */
if (!curr || curr->val != num) {
return false;
}
for (int i = 0; i < level; i++) {
if (update[i]->forward[i] != curr) {
break;
}
/* Right. i Update the status of the layer , take forward Point to the next hop of the deleted node */
update[i]->forward[i] = curr->forward[i];
}
delete curr;
/* Update the current level */
while (level > 1 && head->forward[level - 1] == nullptr) {
level--;
}
return true;
}
int randomLevel() {
int lv = 1;
/* Random generation lv */
while (dis(gen) < P_FACTOR && lv < MAX_LEVEL) {
lv++;
}
return lv;
}
};
Execution time :68 ms, In all C++ Defeated in submission 66.62% Users of
Memory consumption :37.4 MB, In all C++ Defeated in submission 26.23% Users of
Complexity analysis
Time complexity : O(logn), among n by add Number of calls . Detailed analysis of reference problem solution description .
Spatial complexity : O(n), among n by add Number of calls . Detailed analysis of reference problem solution description .
版权声明
本文为[[email protected]]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/208/202207270133077827.html
边栏推荐
- opiodr aborting process unknown ospid (21745) as a result of ORA-609
- Detailed explanation of const usage in C language
- It's too strong. An annotation handles the data desensitization returned by the interface
- DNS记录类型及相关名词解释
- Yilingsi T35 FPGA drives LVDS display screen
- “满五唯一”和“满二唯一”是什么?有什么不同?
- volatile关键字及其作用
- 消息被拒MQ
- Bulk copy baby upload prompt garbled, how to solve?
- Best practices of opentelemetry in service grid architecture
猜你喜欢

$128million! IQM, a Finnish quantum computing company, was supported by the world fund

阿里 Seata 新版本终于解决了 TCC 模式的幂等、悬挂和空回滚问题

185. 部门工资前三高的所有员工(必会)

be based on. NETCORE development blog project starblog - (16) some new functions (monitoring / statistics / configuration / initialization)

spark学习笔记(六)——sparkcore核心编程-RDD行动算子

Practice of online problem feedback module (XV): realize the function of online updating feedback status

【1206. 设计跳表】

IDEA 连接数据库查询数据后控制台表头中文乱码的解决方法

Portraiture5全新升级版磨皮滤镜插件神器

Worthington果胶酶的特性及测定方案
随机推荐
Abbkine AbFluor 488 细胞凋亡检测试剂盒特点及实验建议
unity游戏,隐私协议最简单解决方案!仅3行代码就搞定!(转载)
Marqueeview realizes sliding display effect
PIP3 setting alicloud
字节一面:TCP 和 UDP 可以使用同一个端口吗?
30分钟彻底弄懂 synchronized 锁升级过程
docker 创建mysql 8.x容器,支持mac ,arm架构芯片
177. 第N高的薪水(简单)
PyCharm中Debug模式进行调试详解
Single case mode (double check lock)
浅浅梳理一下双轴快排(DualPivotQuickSort)
“date: write error: No space left on device”解决
Skywalking系列学习之告警通知源码分析
volatile关键字及其作用
Common events of window objects
A test class understands beanutils.copyproperties
30 minutes to thoroughly understand the synchronized lock upgrade process
Pytoch loss function summary
Localstorage and sessionstorage
OC-消息机制