力扣labuladong一刷day54天前缀树

news2024/11/28 17:06:43

力扣labuladong一刷day54天前缀树

文章目录

      • 力扣labuladong一刷day54天前缀树
      • 一、208. 实现 Trie (前缀树)
      • 二、648. 单词替换
      • 三、211. 添加与搜索单词 - 数据结构设计
      • 四、1804. 实现 Trie (前缀树) II
      • 五、677. 键值映射

一、208. 实现 Trie (前缀树)

题目链接:https://leetcode.cn/problems/implement-trie-prefix-tree/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china
思路:类似于下图就是前缀树,本质是多叉树,只不过表示子节点的数组是通过字母进行索引的,叶子节点有值来表示。
在这里插入图片描述

class Trie {

    Node root = null;
    class Node{
        int v = 0;
        Node[] child = new Node[26];
    }
    public Trie() {

    }

    public void insert(String word) {
        if (search(word)) {
            return;
        }
        root = addNode(root, word, 0);
    }

    public boolean search(String word) {
        Node node = getNode(root, word);
        if (node == null || node.v == 0) {
            return false;
        }
        return true;
    }

    public boolean startsWith(String prefix) {
        return getNode(root, prefix) != null;
    }

    Node getNode(Node node, String word) {
        Node p = node;
        for (int i = 0; i < word.length(); i++) {
            if (p == null) {
                return null;
            }
            p = p.child[word.charAt(i)-'a'];
        }
        return p;
    }

    Node addNode(Node node, String word, int i) {
        if (node == null) {
            node = new Node();
        }
        if (i == word.length()) {
            node.v = 1;
            return node;
        }
        int c = word.charAt(i) - 'a';
        node.child[c] = addNode(node.child[c], word, i+1);
        return node;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

二、648. 单词替换

题目链接:https://leetcode.cn/problems/replace-words/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china
思路:和上题一样,也是前缀树的应用,只不过多了一个最短前缀替换。

class Solution {
    public String replaceWords(List<String> dictionary, String sentence) {
        Trie trie = new Trie();
        for (String s : dictionary) {
            trie.insert(s);
        }
        String[] split = sentence.split(" ");
        StringBuilder bf = new StringBuilder();
        for (String s : split) {
            String ms = trie.minSearch(s);
            if ("".equals(ms)) {
                bf.append(s);
            }else {
                bf.append(ms);
            }
            bf.append(" ");
        }
        bf.deleteCharAt(bf.length()-1);
        return bf.toString();
    }

    class Node {
        int v = 0;
        Node[] child = new Node[26];
    }
    class Trie {
        Node root = null;

        void insert(String word) {
            root = addNode(root, word, 0);
        }

        String minSearch(String word) {
            Node p = root;
            for (int i = 0; i < word.length(); i++) {
                if (p == null) return "";
                if (p.v == 1) {
                    return word.substring(0, i);
                }
                p = p.child[word.charAt(i)-'a'];
            }
            if (p != null && p.v == 1) return word;
            return "";
        }

        boolean search(String word) {
            Node node = getNode(word);
            if (node == null || node.v == 0) return false;
            return true;
        }

        Node getNode(String word) {
            Node p = root;
            for (int i = 0; i < word.length(); i++) {
                if (p == null) return null;
                p = p.child[word.charAt(i)-'a'];
            }
            return p;
        }

        Node addNode(Node node, String word, int i) {
            if (node == null) {
                node = new Node();
            }
            if (i == word.length()) {
                node.v = 1;
                return node;
            }
            int c = word.charAt(i)-'a';
            node.child[c] = addNode(node.child[c], word, i+1);
            return node;
        }
    }
}

三、211. 添加与搜索单词 - 数据结构设计

题目链接:https://leetcode.cn/problems/design-add-and-search-words-data-structure/description/
思路:本题还是前缀树,和上一题类似,唯一不同的点是多了一个模式串匹配。

class WordDictionary {
    Node root = null;
    public WordDictionary() {

    }

    public void addWord(String word) {
        root = addNode(root, word, 0);
    }

    public boolean search(String word) {
        return traverse(root, word, 0);
    }

    boolean traverse(Node node, String word, int i) {
        if (node == null) return false;
        if (i == word.length()) {
            return node.v == 1;
        }
        if ('.' == word.charAt(i)) {
            for (int j = 0; j < 26; j++) {
                boolean flag = traverse(node.child[j], word, i + 1);
                if (flag) return flag;
            }
        }else {
            return traverse(node.child[word.charAt(i)-'a'], word, i+1);
        }
        return false;
    }

    Node addNode(Node node, String word, int i) {
        if (node == null) {
            node = new Node();
        }
        if (i == word.length()) {
            node.v = 1;
            return node;
        }
        int c = word.charAt(i)-'a';
        node.child[c] = addNode(node.child[c], word, i+1);
        return node;
    }

}
class Node {
    int v;
    Node[] child = new Node[26];
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */

四、1804. 实现 Trie (前缀树) II

题目链接:https://leetcode.cn/problems/implement-trie-ii-prefix-tree/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china
思路:本题的前缀树多增加了一个功能就是删除节点,删除节点要考虑的就比较多了,到达value的位置要把数量减一,然后在后序位置删除,如果值大于0直接返回就行,不用删除节点,如果值不大于0就需要看该节点的child是否全为null,如果是返回Null就删除了,不是的话保留。

class Trie {
    Node root;
    public Trie() {

    }

    public void insert(String word) {
        root = addNode(root, word, 0);
    }

    public int countWordsEqualTo(String word) {
        Node node = getNode(word);
        if (null == node) return 0;
        return node.v;
    }

    public int countWordsStartingWith(String prefix) {
        Node node = getNode(prefix);
        if (node == null) return 0;
        return traverse(node, 0);
    }

    public void erase(String word) {
        if (getNode(word) == null) return;
        root = deleteNode(root, word, 0);
    }
    Node deleteNode(Node node, String word, int i) {
        if (node == null) return null;
        if (i == word.length()) {
            if (node.v > 0) node.v--;
        }else {
            int c = word.charAt(i)-'a';
            node.child[c] = deleteNode(node.child[c], word, i+1);
        }
        if (node.v > 0) return node;
        for (int j = 0; j < 26; j++) {
            if (node.child[j] != null) {
                return node;
            }
        }
        return null;
    }
    int traverse(Node node, int num) {
        if (node == null) return 0;
        num = node.v;
        for (int i = 0; i < 26; i++) {
            num += traverse(node.child[i], num);
        }
        return num;
    }

    Node addNode(Node node, String word, int i) {
        if (node == null) {
            node = new Node();
        }
        if (i == word.length()) {
            node.v += 1;
            return node;
        }
        int c = word.charAt(i)-'a';
        node.child[c] = addNode(node.child[c], word, i+1);
        return node;
    }

    Node getNode(String word) {
        Node p = root;
        for (int i = 0; i < word.length(); i++) {
            if (p == null) return null;
            p = p.child[word.charAt(i)-'a'];
        }
        return p;
    }
}
class Node{
    int v = 0;
    Node[] child = new Node[26];
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * int param_2 = obj.countWordsEqualTo(word);
 * int param_3 = obj.countWordsStartingWith(prefix);
 * obj.erase(word);
 */

五、677. 键值映射

题目链接:https://leetcode.cn/problems/map-sum-pairs/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china
思路:关键点是前缀查询,先获取到前缀的节点,然后广度优先遍历,前序位置记录节点位置。

class MapSum {
    Node root = null;
    public MapSum() {

    }

    public void insert(String key, int val) {
        root = addNode(root, key, val, 0);
    }

    public int sum(String prefix) {
        Node node = getNode(prefix);
        if (node == null) return 0;
        return traverse(node, 0);
    }
    int traverse(Node node, int num) {
        if (node == null) return 0;
        num = node.v;
        for (int i = 0; i < 26; i++) {
            num += traverse(node.child[i], num);
        }
        return num;
    }
    

    Node getNode(String word) {
        Node p = root;
        for (int i = 0; i < word.length(); i++) {
            if (p == null) return null;
            p = p.child[word.charAt(i)-'a'];
        }
        return p;
    }
    Node addNode(Node node, String word, int value, int i) {
        if (node == null) {
            node = new Node();
        }
        if (i == word.length()) {
            node.v = value;
            return node;
        }
        int c = word.charAt(i) - 'a';
        node.child[c] = addNode(node.child[c], word, value, i+1);
        return node;
    }

}
class Node {
    int v = 0;
    Node[] child = new Node[26];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1365347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[答疑]漏斗图,领域驱动设计叒创新了?

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 albert 2024-1-1 21:11 这篇文章说用DDD重构****&#xff0c;演示了一种漏斗图&#xff0c;请教潘老师&#xff0c;这个图是DDD提出来的吗&#xff0c;您怎么评价&#xff1f; UMLChi…

系列三十五、获取Excel中的总记录数

一、获取Excel中的总记录数 1.1、概述 使用EasyExcel开发进行文件上传时&#xff0c;通常会碰到一个问题&#xff0c;那就是Excel中的记录数太多&#xff0c;使用传统的方案进行文件上传&#xff0c;很容易就超时了&#xff0c;这时可以通过对用户上传的Excel中的数量进行限制…

优雅的通过Shell脚本生成Go的程序包

前言 随着Go语言的普及&#xff0c;越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署&#xff08;CI/CD&#xff09;工具&#xff0c;用于自动化构建、测试和部署Go程序包&#xff0c;但存在一些部署在ECS服务器的Go程序包或需要手动编译…

编译原理Lab4-使用LightIR框架自动产生cminus-f语言的LLVM IR

[[#实验框架|实验框架]][[#实验过程|实验过程]] [[#实验过程#全局变量的设计|全局变量的设计]][[#实验过程#1ASTProgram|1ASTProgram]][[#实验过程#2ASTNum|2ASTNum]][[#实验过程#3ASTVarDeclaration|3ASTVarDeclaration]][[#实验过程#4ASTFunDeclaration|4ASTFunDeclaration]]…

概率论与数理统计 知识点+课后习题

文章目录 &#x1f496; [学习资源整合](https://www.cnblogs.com/duisheng/p/17872980.html)&#x1f4da; 总复习&#x1f4d5; 知识点⭐ 常用分布的数学期望和方差 &#x1f4d9; 选择题&#x1f4d9; 填空题&#x1f4d9; 大题1. 概率2. 概率3. 概率4. P5. 概率6. 概率密度…

读元宇宙改变一切笔记01_起源

1. 元宇宙是我们下一个生存之地 1.1. 1968年&#xff0c;只有不到10%的美国家庭拥有彩色电视&#xff0c;但当年票房排名第二位的电影《2001&#xff1a;太空漫游》&#xff08;2001: A Space Odyssey&#xff09;设想了这样的未来 1.1.1. 斯坦利库布里克(Stanley Kubrick) …

react-router-domV6.21.1版本结合ant design mobile的TabBar标签栏和Popup弹出层实现移动端路由配置

react-router-demo react-router-dom在V6版本之后更换了很多的API名称&#xff0c;在ant design mobile的TabBar配置中还是之前的旧版本&#xff0c;比如使用了switch组件等。我们在这里使用新版本的react-router-dom进行react移动端的配置 首先使用npm下载最新版的react-rout…

【前端设计】小球loading动画

欢迎来到前端设计专栏&#xff0c;本专栏收藏了一些好看且实用的前端作品&#xff0c;使用简单的html、css语法打造创意有趣的作品&#xff0c;为网站加入更多高级创意的元素。 html <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

YOLOv5改进 | 主干篇 | CSWinTransformer交叉形窗口网络改进特征融合层

一、本文介绍 本文给大家带来的改进机制是CSWin Transformer,其基于Transformer架构,创新性地引入了交叉形窗口自注意力机制,用于有效地并行处理图像的水平和垂直条带,形成交叉形窗口以提高计算效率。它还提出了局部增强位置编码(LePE),更好地处理局部位置信息,我将其…

File-一个IO流中至关重要的类

File类 概述&#xff1a;文件和目录路径名的抽象表示&#xff0c;File 对象就代表一个路径 对与File而言&#xff0c;其封装的并不是一个真正存在的文件&#xff0c;仅仅是一个路径名而已。它可以是存在的&#xff0c;也可以是不存在的。将来要通过具体的操作把这个路径的内容…

构建高效PythonWeb:GraphQL+Sanic

1.1 简介&#xff1a;在当今快速发展的技术时代&#xff0c;Web应用的性能和灵活性变得越来越重要。在众多技术中&#xff0c;GraphQL和Sanic以其独特的优势脱颖而出。GraphQL&#xff0c;作为一个强大的数据查询语言&#xff0c;为前端和后端之间的通信提供了极大的灵活性。而…

HCIA-Datacom题库(自己整理分类的)_09_Telent协议【13道题】

一、单选 1.某公司网络管理员希望能够远程管理分支机构的网络设备&#xff0c;则下面哪个协议会被用到&#xff1f; RSTP CIDR Telnet VLSM 2.以下哪种远程登录方式最安全&#xff1f; Telnet Stelnet v100 Stelnet v2 Stelnet v1 解析&#xff1a; Telnet 明文传输…

Oracle-expdp备份变慢问题分析

问题背景&#xff1a; 应用有一个每日跑批之前的备份作业&#xff0c;通过expdp备份应用的用户数据&#xff0c;数据量大概为600G左右&#xff0c;正常情况下可以在20分钟内跑完&#xff0c;但最近expdp备份完成时间却突然猛涨到要2小时32分才能备份完&#xff0c;导致后续的跑…

使用 MONAI 加载和保存各种格式的医学图像

本教程属于实战&#xff0c;手把手教你加载各种医学图像数据&#xff08;nii.gz, .dcm, .png等&#xff09;。并学会查看医学图像数据的元数据&#xff08;shape, affine, orientation&#xff09;。学会使用monai全方位了解你的数据&#xff0c;并把它用于之后的深度学习训练。…

最新ChatGPT网站系统源码+详细搭建部署教程+Midjourney绘画AI绘画

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

数据版本控制利器LakeFS的介绍,以及其使用方法,与其它工具结合案例

LakeFS介绍 LakeFS 是一个开源的数据湖版本控制系统&#xff0c;可以帮助用户管理和控制数据湖中的数据版本。以下是LakeFS的一些主要用处和功能介绍&#xff1a; 数据版本控制&#xff1a;LakeFS 提供了类似于 Git 的版本控制功能&#xff0c;可以跟踪和管理数据湖中的数据版…

智能合约:3分钟开发ERC20 token(2)

0.前言 上一节我们讲到了开发智能合约的准备工作&#xff0c;以及在线编程平台remix 智能合约&#xff08;1&#xff09; 这一节讲解如何开发、发行一个代币&#xff0c;并具备包括代币铸造mint&#xff0c;转账transfer和销毁burn功能&#xff0c;并确保合约拥有者owner的权限…

HEVC 视频扩展安装包,WIN10上看苹果的照片格式

苹果手机照片放电脑上&#xff0c;后缀名称.HEIC&#xff0c;打开居然要下载 HEVC 视频扩展包才能查看&#xff0c;网盘找到一个记录一下&#xff0c;安装后就可以查看苹果手机照片了。 链接&#xff1a;https://pan.baidu.com/s/13ye9_6brXD32jWAjfS47gQ?pwd36k5 提取码&am…

vue结合Cesium加载gltf模型

Cesium支持什么格式&#xff1f; Cesium支持的格式包括&#xff1a;3D模型格式&#xff08;如COLLADA、gITF、OBJ&#xff09;、影像格式&#xff08;如JPEG、PNG、GeoTIFF&#xff09;、地形格式&#xff08;如STL、Heightmap&#xff09;、矢量数据格式&#xff08;如GeoJSON…

[AutoSar]基础部分 RTE 05 Port的实例化和初始化

目录 关键词平台说明一、端口类型二、端口的实例化2.1 创建application port2.2 实例化 三、初始化 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、端口类型 如下图所示&am…