当前位置:网站首页>[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
边栏推荐
猜你喜欢

消息被拒MQ
![[从零开始学习FPGA编程-54]:高阶篇 - 基于IP核的FPGA开发-PLL锁相环IP核的原理与配置(Altera)](/img/4f/f75cfeb4422120ef9ac70cdeb0a840.png)
[从零开始学习FPGA编程-54]:高阶篇 - 基于IP核的FPGA开发-PLL锁相环IP核的原理与配置(Altera)

Common events of window objects

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

周全的照护 解析LYRIQ锐歌电池安全设计

安全员及环保员岗位职责

深度学习——词汇embedded、Beam Search

Details of impala implementation plan

Functions that should be selected for URL encoding and decoding

Deep learning vocabulary embedded, beam search
随机推荐
opiodr aborting process unknown ospid (21745) as a result of ORA-609
day6
Single case mode (double check lock)
be based on. NETCORE development blog project starblog - (16) some new functions (monitoring / statistics / configuration / initialization)
Skywalking系列学习之告警通知源码分析
win10/win11无损扩大C盘空间,跨盘合并C、E盘
shell awk
Analysis of [paper] pointlanenet papers
Byte side: can TCP and UDP use the same port?
Bulk copy baby upload prompt garbled, how to solve?
数据湖(二十):Flink兼容Iceberg目前不足和Iceberg与Hudi对比
IDEA 连接数据库查询数据后控制台表头中文乱码的解决方法
带你了解什么是 Web3.0
Functions that should be selected for URL encoding and decoding
深入理解Mysql索引底层数据结构与算法
flask_restful中reqparse解析器继承
Data Lake (20): Flink is compatible with iceberg, which is currently insufficient, and iceberg is compared with Hudi
Submodule cache cache failure
自己梳理的LocalDateTime的工具类
DNS记录类型及相关名词解释