当前位置:网站首页>【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)。
边栏推荐
- Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
- Enterprise firewall management, what firewall management tools are there?
- Get piggy homestay (short-term rental) data
- Quartus 使用 tcl 文件快速配置管脚
- Building a cloud-native DevOps environment
- 获取小猪民宿(短租)数据
- solidity
- 6134. Find the closest node to the given two nodes - force double hundred code
- 【MySQL篇】初识数据库
- A brief analysis of mobile APP security testing in software testing, shared by a third-party software testing agency in Beijing
猜你喜欢

2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...

在CentOS下安装MySQL

nodejs--process

Access the selected node in the console

Flink Yarn Per Job - 提交流程一

技术分享 | 接口测试中如何使用Json 来进行数据交互 ?

【MySQL系列】MySQL索引事务

【MySQL篇】初识数据库

The third chapter of the imitation cattle network project: develop the core functions of the community (detailed steps and ideas)

sys_kill system call
随机推荐
Department project source code sharing
Calculate the distance between two points
伸展树的特性及实现
C language - branch statement and loop statement
Get piggy homestay (short-term rental) data
Calculate the midpoint between two points
如何用Redis实现分布式锁?
6134. Find the closest node to the given two nodes - force double hundred code
Various Joins of Sql
ELK日志采集
cdh6 opens oozieWeb page, Oozie web console is disabled.
Avoid hidden text when loading fonts
Sql之各种Join
cdh的hue上oozie启动报错,Cannot allocate containers as requested resource is greater than maximum allowed
The Spark of Sql join on the and and where
@WebServlet注解(Servlet注解)
20220725 Information update
经典文献阅读之--DLO
Flink学习第五天——Flink可视化控制台依赖配置和界面介绍
PostgreSQL Basics--Common Commands