文章目录
bitmap求交集


2个有序链表



多个有序链表

- 为什么非最大的所有都要往后移动呢?因为现在已经知道交集即使有,也最小都是这个目前最大的了,其他不是最大的不可能是交集,所有除了最大其他都往后移动就行
跳表

- 跳表(Skip List)是一种用于高效查找、插入和删除有序元素的数据结构,结合了链表和二分查找的思想,空间换时间。它通过构建多层链表来实现快速搜索,平均时间复杂度为 O(logn),且实现比平衡树更简单。
- 多层链表结构:
- 底层是完整的有序链表,包含所有元素。
- 每一层都是下一层的"快速通道",节点随机晋升到更高层,形成类似"索引"的结构。
- 高层节点稀疏,低层节点密集。
- 随机晋升:
- 插入新节点时,通过随机算法(如抛硬币)决定晋升到多少层。
- 晋升概率通常为1/2,即每个节点有 50% 的概率出现在上一层。
go
package main
import (
"fmt"
"math/rand"
"time"
)
const (
MaxLevel = 16 // 跳表的最大层数
Probability = 0.5 // 每增加一层的概率
)
// 节点结构
type Node struct {
value int
next []*Node
}
// 跳表结构
type SkipList struct {
head *Node
level int
}
// 创建新节点
func newNode(value, level int) *Node {
return &Node{
value: value,
next: make([]*Node, level),
}
}
// 创建跳表
func NewSkipList() *SkipList {
rand.Seed(time.Now().UnixNano())
return &SkipList{
head: newNode(0, MaxLevel),
level: 1,
}
}
// 随机层数
func (sl *SkipList) randomLevel() int {
level := 1
for rand.Float64() < Probability && level < MaxLevel {
level++
}
return level
}
// 查找
func (sl *SkipList) Search(target int) bool {
curr := sl.head
for i := sl.level - 1; i >= 0; i-- {
for curr.next[i] != nil && curr.next[i].value < target {
curr = curr.next[i]
}
}
curr = curr.next[0]
return curr != nil && curr.value == target
}
// 插入
func (sl *SkipList) Insert(value int) {
update := make([]*Node, MaxLevel)
curr := sl.head
for i := sl.level - 1; i >= 0; i-- {
for curr.next[i] != nil && curr.next[i].value < value {
curr = curr.next[i]
}
update[i] = curr
}
level := sl.randomLevel()
if level > sl.level {
for i := sl.level; i < level; i++ {
update[i] = sl.head
}
sl.level = level
}
newNode := newNode(value, level)
for i := 0; i < level; i++ {
newNode.next[i] = update[i].next[i]
update[i].next[i] = newNode
}
}
// 打印跳表(调试用)
func (sl *SkipList) Print() {
for i := sl.level - 1; i >= 0; i-- {
curr := sl.head.next[i]
fmt.Printf("Level %d: ", i+1)
for curr != nil {
fmt.Printf("%d ", curr.value)
curr = curr.next[i]
}
fmt.Println()
}
}
func main() {
sl := NewSkipList()
sl.Insert(1)
sl.Insert(3)
sl.Insert(5)
sl.Insert(7)
sl.Insert(9)
sl.Print()
fmt.Println("Search 5:", sl.Search(5)) // true
fmt.Println("Search 6:", sl.Search(6)) // false
}
- 两跳表求交集

go
func IntersectionOfSkipList(lists ...*skiplist.SkipList) (res *skiplist.SkipList) {
if len(lists) == 0 {
return nil
}
if len(lists) == 1 {
return lists[0]
}
res = skiplist.New(skiplist.Uint64)
nodes := make([]*skiplist.Element, len(lists))
for i, list := range lists {
if list == nil || list.Len() == 0 {
return nil
}
nodes[i] = list.Front()
}
for {
var maxList map[int]struct{} // 用于存储当前值最大的节点(可能有多个,所以用map来模仿集合)
var maxValue uint64 = 0
for i, node := range nodes {
if node.Key().(uint64) > maxValue {
maxValue = node.Key().(uint64)
maxList = map[int]struct{}{i: {}}
} else if node.Key().(uint64) == maxValue {
maxList[i] = struct{}{}
}
}
if len(maxList) == len(lists) { // 所有node节点都指向了最大值,可以添加到交集
res.Set(nodes[0].Key(), nodes[0].Value)
for i, node := range nodes { // 所有node节点往后移
nodes[i] = node.Next()
if nodes[i] == nil {
return
}
}
} else {
for i, node := range nodes {
if _, exists := maxList[i]; !exists {
nodes[i] = node.Next()
if nodes[i] == nil {
return
}
}
}
}
}
}
go
func (sl *SkipList) Intersection(other *SkipList) []int {
result := []int{}
// 从最底层第一个节点开始
p1 := sl.head.next[0]
p2 := other.head.next[0]
for p1 != nil && p2 != nil {
if p1.value == p2.value {
result = append(result, p1.value)
p1 = p1.next[0]
p2 = p2.next[0]
} else if p1.value < p2.value {
p1 = p1.next[0]
} else {
p2 = p2.next[0]
}
}
return result
}
// 加速查找
// Search查找一个元素,返回是否存在
func (sl *SkipList) Search(value int) bool {
curr := sl.head
for i := sl.level - 1; i >= 0; i-- {
for curr.next[i] != nil && curr.next[i].value < value {
curr = curr.next[i]
}
}
curr = curr.next[0]
return curr != nil && curr.value == value
}
// 交集(基于快速查找)
func (sl1 *SkipList) IntersectionWith(sl2 *SkipList) []int {
result := []int{}
curr := sl2.head.next[0] // 遍历第二个跳表的底层节点
for curr != nil {
if sl1.Search(curr.value) { // 用第一个跳表查找
result = append(result, curr.value)
}
curr = curr.next[0]
}
return result
}
- 多跳表求交集
go
// Search查找一个元素,返回是否存在
func (sl *SkipList) Search(value int) bool {
curr := sl.head
for i := sl.level - 1; i >= 0; i-- {
for curr.next[i] != nil && curr.next[i].value < value {
curr = curr.next[i]
}
}
curr = curr.next[0]
return curr != nil && curr.value == value
}
// 多跳表交集(基于跳表加速查找)
func IntersectionSkipLists(lists []*SkipList) []int {
if len(lists) == 0 {
return []int{}
}
if len(lists) == 1 {
// 只有一个跳表,直接返回所有元素
result := []int{}
curr := lists[0].head.next[0]
for curr != nil {
result = append(result, curr.value)
curr = curr.next[0]
}
return result
}
// 1. 找到元素最少的跳表作为主跳表
mainList := lists[0]
for _, sl := range lists[1:] {
if sl.Size() < mainList.Size() {
mainList = sl
}
}
// 2. 依次遍历主跳表的元素
result := []int{}
curr := mainList.head.next[0]
for curr != nil {
found := true
for _, sl := range lists {
if sl == mainList {
continue
}
if !sl.Search(curr.value) {
found = false
break
}
}
if found {
result = append(result, curr.value)
}
curr = curr.next[0]
}
return result
}
// Size 计算跳表元素数量
func (sl *SkipList) Size() int {
cnt := 0
curr := sl.head.next[0]
for curr != nil {
cnt++
curr = curr.next[0]
}
return cnt
}