1206. 设计跳表

题目描述:

不使用任何库函数,设计一个 跳表 。

跳表 是在 O(log(n)) 时间内完成增加、删除、搜索操作的数据结构。跳表相比于树堆与红黑树,其功能与性能相当,并且跳表的代码长度相较下更短,其设计思想与链表相似。

例如,一个跳表包含 [30, 40, 50, 60, 70, 90] ,然后增加 80、45 到跳表中,以下图的方式操作。

跳表中有很多层,每一层是一个短的链表。在第一层的作用下,增加、删除和搜索操作的时间复杂度不超过 O(n)。跳表的每一个操作的平均时间复杂度是 O(log(n)),空间复杂度是 O(n)。

了解更多 : https://en.wikipedia.org/wiki/Skip_list 🔗

在本题中,你的设计应该要包含这些函数:

  • bool search(int target) : 返回target是否存在于跳表中。
  • void add(int num): 插入一个元素到跳表。
  • bool erase(int num): 在跳表中删除一个值,如果 num 不存在,直接返回false. 如果存在多个 num ,删除其中任意一个即可。 注意,跳表中可能存在多个相同的值,你的代码需要处理这种情况。

测试用例:

示例 1:

输入
["Skiplist", "add", "add", "add", "search", "add", "search", "erase", "erase", "search"]
[[], [1], [2], [3], [0], [4], [1], [0], [1], [1]]
输出
[null, null, null, null, false, null, true, false, true, false]
解释
Skiplist skiplist = new Skiplist();
skiplist.add(1);
skiplist.add(2);
skiplist.add(3);
skiplist.search(0);   // 返回 false
skiplist.add(4);
skiplist.search(1);   // 返回 true
skiplist.erase(0);    // 返回 false,0 不在跳表中
skiplist.erase(1);    // 返回 true
skiplist.search(1);   // 返回 false,1 已被擦除

限制及提示:

  • <= num, target <= 2 * 10^4
  • 调用search, add, erase操作次数不大于 5 * 10^4

解题分析及思路:

这一题先不看题目的要求怎么去设计跳表,而是去完成这几个方法,你就会发现其实算不上困难题。

可以采用一个map去存储num再这个跳表中的个数,插入时,个数加一,删除时,个数减一即可

构造Skiplist结构体,并初始化

type Skiplist struct {
	nums map[int]int
}

func Constructor() Skiplist {
	return Skiplist{
		make(map[int]int),
	}
}

定义三个方法,对map进行取值后判断即可。

func (this *Skiplist) Search(target int) bool {
	if count, ok := this.nums[target]; ok && count > 0 {
		return true
	}
	return false
}

func (this *Skiplist) Add(num int) {
	this.nums[num]++
}

func (this *Skiplist) Erase(num int) bool {
	if count, ok := this.nums[num]; ok && count > 0 {
		this.nums[num]--
		return true
	}
	return false
}

复杂度:

  • 时间复杂度:O(1)
  • 空间复杂度:O(n)

执行结果:

  • 执行用时: 36 ms, 在所有 Go 提交中击败了100.00%的用户
  • 内存消耗:9.5 MB, 在所有 Go 提交中击败了57.56% 的用户

通过次数 34.4K 提交次数 50.9K 通过率 67.4%

Related Posts

41. 缺失的第一个正数

## 题目描述:给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。示例 1:输入:nums = [1,2,0] 输出:3 解释:范围 [1,2] 中的数字都在数组中。示例 2:``` 输入:nums = [3,4,-1,1] 输出:2 解释

read more

42. 接雨水

## 题目描述:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 ![

read more

736. Lisp语法解析

## 题目描述:给你一个类似 Lisp 语句的字符串表达式 expression,求出其计算结果。表达式语法如下所示: - 表达式可以为整数,let 表达式,add 表达式,mult 表达式,或赋值的变量。表达式的结果总是一个整数。 - (整数可以是正整数、负整数、0) - let 表达式采用 "(let v1 e1 v2 e2 ... vn en expr)" 的形式,其中 let 总

read more

899. 有序队列

## 题目描述:给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 。**测试用例:**示例 1: ``` 输入:s = "cba", k = 1 输出:"acb" 解释: 在第一步中,我们将第一个字符(“c”)移动到最后,获得字符串 “bac”。 在第二步中,我们将第

read more

1189. “气球” 的最大数量

## 题目描述:给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"示例 1:****

read more

1261. 在受污染的二叉树中查找元素

## 题目描述:给出一个满足下述规则的二叉树:1. root.val == 0 2. 如果 treeNode.val == x 且 treeNode.left != null,那么 treeNode.left.val == 2 * x + 1 3. 如果 treeNode.val == x 且 treeNode.right != null,那么 treeNode.right.val ==

read more