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

多御安全浏览器android版更新至1.7,改进加密协议

1个月写900多条用例,二线城市年薪33W+的测试经理能有多卷?

DRF generating serialization class code

Flink Yarn Per Job - Yarn应用

Bean的生命周期

在CentOS下安装MySQL

2022第六届强网杯部分wp

C语言——分支语句和循环语句

Get piggy homestay (short-term rental) data

在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password YES) 拒绝访问问题解决
随机推荐
thinkphp漏洞总结
[C language advanced] file operation (2)
Access the selected node in the console
numpy.where
Leetcode 129求根节点到叶节点数字之和、104二叉树的最大深度、8字符串转换整数(atoi)、82删除排序链表中的重复元素II、204二分查找、94二叉树的中序遍历、144二叉树的前序遍历
Flink Yarn Per Job - 提交流程一
ICLR 2022 Best Paper: Partial Label Learning Based on Contrastive Disambiguation
论文理解【RL - Exp Replay】—— Experience Replay with Likelihood-free Importance Weights
color transparency parameter
Appears in oozie on CDH's hue, error submitting Coordinator My Schedule
Several interview questions about golang concurrency
Check if point is inside rectangle
ELK log collection
类型“FC<Props>”的参数不能赋给类型“ForwardRefRenderFunction<unknown, Props>”的参数。 属性“defaultProps”的类型不兼容。 不
企业防护墙管理,有什么防火墙管理工具?
架构基本概念和架构本质
软件测试之移动APP安全测试简析,北京第三方软件检测机构分享
在MySQL中使用MD5加密【入门体验】
Share an interface test project (very worth practicing)
Bean的生命周期