Trie树(前缀树/字典树)

  • 定义:Trie树,又经常叫前缀树字典树等等
  • 百度百科:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
  • 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
  • 它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

0、定义

1、操作

2、Go实现

  • 实现参考:leetcode208.实现 Trie (前缀树)
  • Insert操作
  • Search操作
type Trie struct {
    next   [26]*Trie // 下一级指针,如不限于小写字母,[26]=>[256]
    ending int       // 次数(可以改为bool)
}

func Constructor() Trie {
    return Trie{
        next:   [26]*Trie{},
        ending: 0,
    }
}

// 插入word
func (this *Trie) Insert(word string) {
    temp := this
    for _, v := range word {
        value := v - 'a'
        if temp.next[value] == nil {
            temp.next[value] = &Trie{
                next:   [26]*Trie{},
                ending: 0,
            }
        }
        temp = temp.next[value]
    }
    temp.ending++
}

// 查找
func (this *Trie) Search(word string) bool {
    temp := this
    for _, v := range word {
        value := v - 'a'
        if temp = temp.next[value]; temp == nil {
            return false
        }
    }
    if temp.ending > 0 {
        return true
    }
    return false
}

// 查找前缀
func (this *Trie) StartsWith(prefix string) bool {
    temp := this
    for _, v := range prefix {
        value := v - 'a'
        if temp = temp.next[value]; temp == nil {
            return false
        }
    }
    return true
}

二进制版本

type Trie struct {
    next []*Trie // 0或者1
    size int     // 次数
}

// 插入num
func (t *Trie) Insert(num int) {
    temp := t
    for i := 31; i >= 0; i-- {
        value := (num >> i) & 1
        if temp.next[value] == nil {
            temp.next[value] = &Trie{
                next: make([]*Trie, 2),
            }
        }
        temp = temp.next[value]
        temp.size++
    }
}

// 查找小于target的数量
func (t *Trie) Search(num int, target int) int {
    res := 0
    temp := t
    for i := 31; i >= 0; i-- {
        if temp == nil { // 直接返回
            return res
        }
        value := (num >> i) & 1
        targetValue := (target >> i) & 1
        if targetValue > 0 { // target该位为1
            if temp.next[value] != nil {
                res = res + temp.next[value].size
            }
            temp = temp.next[1-value] // value ^ (1-value) = 1 => 往1-value走
        } else {
            temp = temp.next[value] // value ^ value = 0 // 往value走
        }
    }
    return res
}

// 查找异或对应的最大值
func (t *Trie) getMaxValue(num int) int {
    res := 0
    temp := t
    for i := 31; i >= 0; i-- {
        value := (num >> i) & 1
        if temp.next[1-value] != nil { // 能取到1
            res = res | (1 << i) // 结果在该位可以为1,该为置为1
            temp = temp.next[1-value]
        } else {
            temp = temp.next[value]
        }
    }
    return res
}

3、Leetcode

非二进制版本

Title Tag 难度 完成情况
14.最长公共前缀 字符串 Easy 完成
208.实现 Trie (前缀树) 设计、字典树 Medium 完成
211.添加与搜索单词-数据结构设计 设计、字典树、回溯算法 Medium 完成
648.单词替换 字典树、哈希表 Medium 完成
676.实现一个魔法字典 设计、字典树、哈希表、字符串 Medium 完成
720.词典中最长的单词 字典树、哈希表 Easy 完成
1268.搜索推荐系统 字典树、数组、字符串 Medium 完成
面试题17.13.恢复空格 字典树、数组、哈希表、字符串、
动态规划、哈希函数、滚动哈希
Medium 完成
面试题17.17.多次搜索 字典树、数组、哈希表、字符串、
字符串匹配、滑动窗口
Medium 完成
剑指OfferII064.神奇的字典 设计、字典树、哈希表、字符串 Medium 完成

二进制版本

Title Tag 难度 完成情况
421.数组中两个数的最大异或值 位运算、字典树 Medium 完成
1707.与数组中元素的最大异或值 位运算、字典树、数组 Hard 完成
1803.统计异或值在范围内的数对有多少 位运算、字典树、数组 Hard 完成
Copyright © Zhi2014 2023 all right reserved,powered by Gitbook该文件修订时间: 2023-10-23 15:20:51

results matching ""

    No results matching ""