当前位置:网站首页>【Leetcode】1206. Design Skiplist
【Leetcode】1206. Design Skiplist
2022-08-01 23:47:00 【记录算法题解】
题目地址:
https://leetcode.com/problems/design-skiplist/
实现一个跳表。
跳表如下图所示:
其是一个分层有序链表结构(有序指的是按元素大小排序,类似于平衡树),设最下层为第 0 0 0层,向上的层数以此类推。每一层的节点数大致是其上面一层的两倍,而查找元素的时候可以通过高层的快速跳跃实现优化。有个虚拟头结点为搜索的出发节点。核心操作为“前驱查找”,这个操作会找到每一层的小于给定元素 x x x的最后一个节点(如果不存在,则视为找到了头结点)。
每个操作具体如下:
1、查找 x x x是否存在。先对 x x x进行前驱查找,然后看第 0 0 0层找到的那个节点的下一个节点,只需要看其是否值为 x x x即可;
2、添加 x x x。先对 x x x进行前驱查找,然后看第 0 0 0层找到的那个节点,如果那个节点存在,则其为小于 x x x的最后一个节点;如果不存在,那个节点即为头结点。无论怎样,都可以在那个节点之后添加新的值为 x x x的节点。此时,以 50 % 50\% 50%的概率将这个节点插到上一层,插完之后再以 50 % 50\% 50%的概率将这个节点插到更上一层,一直插到最上层或中间停止了为止。
3、删除 x x x。先对 x x x进行前驱查找,然后看第 0 0 0层找到的那个节点,看其下一个节点,如果不存在,或者值不为 x x x,则说明 x x x不存在,直接返回。否则说明找到了,删除之,并向上爬,删除上面层中的 x x x。
代码如下:
class Skiplist {
public:
#define level 8
struct Node {
int val;
vector<Node*> next;
Node(int val) : val(val) {
next.resize(level, nullptr);
}
} *head;
Skiplist() {
head = new Node(-1);
}
~Skiplist() {
delete head;
}
void find(int x, vector<Node*> &pre) {
// 从头结点出发,找到每一层小于x的最后一个节点,如果没找到则赋为头结点
auto p = head;
for (int i = level - 1; i >= 0; i--) {
while (p->next[i] && p->next[i]->val < x) p = p->next[i];
pre[i] = p;
}
}
bool search(int x) {
vector<Node*> pre(level);
find(x, pre);
auto p = pre[0]->next[0];
return p && p->val == x;
}
void add(int x) {
vector<Node*> pre(level);
find(x, pre);
auto p = new Node(x);
// 从下向上每一层添加节点x
for (int i = 0; i < level; i++) {
p->next[i] = pre[i]->next[i];
pre[i]->next[i] = p;
// 以50%的概率退出
if (rand() & 1) break;
}
}
bool erase(int x) {
vector<Node*> pre(level);
find(x, pre);
auto p = pre[0]->next[0];
if (!p || p->val != x) return false;
for (int i = 0; i < level && pre[i]->next[i] == p; i++)
pre[i]->next[i] = p->next[i];
delete p;
return true;
}
};
每个操作平均时间复杂度 O ( log n ) O(\log n) O(logn), n n n为表里已有的元素个数(即最下面一层的节点个数),空间平均 O ( n ) O(n) O(n)。
边栏推荐
- 根本上解决mysql启动失败问题Job for mysqld.service failed because the control process exited with error code
- 12306抢票,极限并发带来的思考?
- 6133. 分组的最大数量
- 2022第六届强网杯部分wp
- 颜色透明参数
- 6134. Find the closest node to the given two nodes - force double hundred code
- Docker搭建Mysql主从复制
- @WebServlet注解(Servlet注解)
- Appears in oozie on CDH's hue, error submitting Coordinator My Schedule
- 辛普森悖论
猜你喜欢
chrome copies the base64 data of an image
What is CICD excuse me
技术分享 | 接口测试中如何使用Json 来进行数据交互 ?
A brief analysis of mobile APP security testing in software testing, shared by a third-party software testing agency in Beijing
cdh6 opens oozieWeb page, Oozie web console is disabled.
[LeetCode304 Weekly Competition] Two questions about the base ring tree 6134. Find the closest node to the given two nodes, 6135. The longest cycle in the graph
Work for 5 years, test case design is bad?To look at the big case design summary
GIF制作-灰常简单的一键动图工具
2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...
Access the selected node in the console
随机推荐
Flink学习第四天——完成第一个Flink 流批一体案例
Architecture basic concept and nature of architecture
2022 6th Strong Net Cup Part WP
Thesis understanding [RL - Exp Replay] - Experience Replay with Likelihood-free Importance Weights
Classical Literature Reading--DLO
Flink Yarn Per Job - Yarn应用
深度学习基础-基于Numpy的循环神经网络(RNN)实现和反向传播训练
Use Jenkins for continuous integration, this knowledge point must be mastered
Flink学习第三天——一文带你了解什么是Flink流?
在MySQL中使用MD5加密【入门体验】
一道golang中关于iota的面试题
Building a cloud-native DevOps environment
Calculate the angle of a line defined by two points
numpy.hstack
C语言——分支语句和循环语句
字节跳动面试官:请你实现一个大文件上传和断点续传
[C language advanced] file operation (2)
Special characters & escapes in bat
【MySQL篇】初识数据库
如何用Redis实现分布式锁?