【Hot 100】208. 實現 Trie (前綴樹)

目錄

  • 引言
  • 實現 Trie (前綴樹)
    • 我的解題
    • 代碼解析
      • 代碼思路分析
      • 優化建議
        • 1. 內存泄漏問題
        • 2. 使用智能指針優化內存管理
        • 3. 輸入合法性校驗(可選)
        • 4. 其他優化
      • 總結

請添加圖片描述

  • 🙋?♂? 作者:海碼007
  • 📜 專欄:算法專欄
  • 💥 標題:【Hot 100】208. 實現 Trie (前綴樹)
  • ?? 寄語:書到用時方恨少,事非經過不知難!

引言

實現 Trie (前綴樹)

  • 🎈 題目鏈接:
  • 🎈 做題狀態:

我的解題

首先需要理解前綴樹的定義,前綴樹是一顆多叉樹,樹根不存儲字母。每一層可能存儲26個不同的字母。然后每一個單詞對應這個多叉樹的一條路徑,并且路徑的結尾會標識是單詞的結尾。

class Trie {
private:bool isEnd;Trie* next[26]; //指針數組,有26個小寫字母public:Trie() {isEnd = false;memset(next, 0, sizeof(next));}// 插入一個單詞void insert(string word) {// node指向根節點并向下遍歷Trie* node = this;for (char c : word){// 判斷當前這個字母是否在當前層存在,如果不存在則創建一個新的樹。if (node->next[c-'a'] == nullptr){node->next[c-'a'] = new Trie();}node = node->next[c-'a'];   // 繼續往下遍歷}// 遍歷到末尾后,需要標識 endnode->isEnd = true;}// 搜索當前單詞是否存在,依次比較每個單詞是否存在每一層中bool search(string word) {Trie* node = this;for (const char& c : word){if (node->next[c-'a'] == nullptr){return false;}node = node->next[c-'a'];}return node->isEnd; // 遍歷到末尾后還需要判斷是否是單詞的結尾}// 判斷這個前綴樹是否包含 prefix 這個前綴bool startsWith(string prefix) {Trie* node = this;for (const char& c : prefix){if (node->next[c-'a'] == nullptr){return false;}node = node->next[c-'a'];}return true;}
};/*** Your Trie object will be instantiated and called as such:* Trie* obj = new Trie();* obj->insert(word);* bool param_2 = obj->search(word);* bool param_3 = obj->startsWith(prefix);*/

代碼解析

該代碼實現了一個基本的前綴樹(Trie)結構,支持插入、搜索和前綴匹配功能。以下是對代碼的詳細分析和優化建議:


代碼思路分析

  1. 數據結構設計

    • isEnd:標記當前節點是否為單詞的結尾。
    • next[26]:一個包含 26 個指針的數組,對應英文小寫字母,用于構建字符到子節點的映射。
  2. 核心方法

    • 插入 (insert): 從根節點開始,逐字符向下遍歷。若字符對應的子節點不存在,則創建新節點。遍歷完成后,標記最后一個節點為單詞結尾。
    • 搜索 (search): 檢查單詞是否存在且最后一個節點被標記為結尾。
    • 前綴匹配 (startsWith): 僅檢查路徑是否存在,無需判斷結尾標記。
  3. 正確性

    • 邏輯正確,符合前綴樹的標準實現。
    • 使用 memset 初始化指針數組,確保初始值為 nullptr

優化建議

1. 內存泄漏問題

當前代碼未釋放動態分配的子節點,導致內存泄漏。需添加析構函數遞歸釋放子節點:

~Trie() {for (int i = 0; i < 26; ++i) {delete next[i]; // 遞歸調用子節點的析構函數}
}
2. 使用智能指針優化內存管理

改用 std::unique_ptr 管理子節點,避免手動釋放內存:

class Trie {
private:bool isEnd;std::array<std::unique_ptr<Trie>, 26> next; // 使用智能指針public:Trie() : isEnd(false) {} // 無需 memsetvoid insert(string word) {Trie* node = this;for (char c : word) {if (!node->next[c - 'a']) {node->next[c - 'a'] = std::make_unique<Trie>();}node = node->next[c - 'a'].get();}node->isEnd = true;}// search 和 startsWith 無需修改
};
3. 輸入合法性校驗(可選)

若需處理非法字符(如大寫字母),可在插入/查詢前添加校驗:

void insert(string word) {for (char c : word) {if (c < 'a' || c > 'z') {throw std::invalid_argument("Invalid character");}}// 原插入邏輯
}
4. 其他優化
  • 空間優化:使用壓縮 Trie 樹(如 Ternary Search Tree)減少內存占用,但會增加實現復雜度。
  • 性能優化:當前時間復雜度為 O(L)(L 為字符串長度),已是最優,無需調整。

總結

代碼邏輯正確,但存在內存泄漏問題。建議通過析構函數或智能指針優化內存管理。其他優化可根據實際需求選擇。改進后的代碼示例(使用智能指針)如下:

#include <memory>   // 用于智能指針 unique_ptr
#include <array>    // 用于固定大小的數組 array
#include <string>   // 用于字符串操作class Trie {
private:// 標記當前節點是否為某個單詞的結尾bool isEnd;// 使用智能指針管理子節點,避免內存泄漏// 數組大小為26,對應英文小寫字母a-zstd::array<std::unique_ptr<Trie>, 26> next;public:// 構造函數:初始化 isEnd 為 false,表示初始時不是單詞結尾// 智能指針數組 next 會自動初始化為 nullptrTrie() : isEnd(false) { }/*** 插入一個單詞到 Trie 樹中* @param word 待插入的單詞*/void insert(const std::string& word) {// 從根節點(this)開始遍歷Trie* node = this;// 逐個字符處理for (char c : word) {// 計算字符對應的索引(a->0, b->1, ..., z->25)int idx = c - 'a';// 如果當前字符的子節點不存在,則創建新節點if (node->next[idx] == nullptr) {node->next[idx] = std::make_unique<Trie>();}// 移動到子節點繼續處理node = node->next[idx].get();  // get() 獲取裸指針}// 標記單詞的最后一個字符節點為結尾node->isEnd = true;}/*** 搜索 Trie 樹中是否存在某個單詞* @param word 待搜索的單詞* @return 如果單詞存在且完整匹配(最后一個字符是結尾),返回 true;否則返回 false*/bool search(const std::string& word) {// 從根節點開始遍歷Trie* node = this;// 逐個字符檢查for (const char& c : word) {int idx = c - 'a';// 如果當前字符的子節點不存在,說明單詞不存在if (node->next[idx] == nullptr) {return false;}// 移動到子節點繼續檢查node = node->next[idx].get();}// 檢查最后一個字符是否被標記為單詞結尾return node->isEnd;}/*** 檢查 Trie 樹中是否存在某個前綴* @param prefix 待檢查的前綴* @return 如果前綴存在(不要求是完整單詞),返回 true;否則返回 false*/bool startsWith(const std::string& prefix) {// 從根節點開始遍歷Trie* node = this;// 逐個字符檢查for (const char& c : prefix) {int idx = c - 'a';// 如果當前字符的子節點不存在,說明前綴不存在if (node->next[idx] == nullptr) {return false;}// 移動到子節點繼續檢查node = node->next[idx].get();}// 只要路徑存在,無論是否是單詞結尾,都返回 truereturn true;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82967.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity3D仿星露谷物語開發42之粒子系統

1、目標 使用例子系統&#xff0c;實現割草后草掉落的特效。 通過PoolManager獲取特效預制體&#xff0c;通過VFXManager來觸發特效。 2、配置例子特效 在Hierarchy -> PersistentScene下創建新物體命名為Reaping。 給該物體添加Particle System組件。 配置例子系統參數…

視覺-語言基礎模型作為高效的機器人模仿學習范式

摘要 近期&#xff0c;視覺語言基礎模型領域取得的進展彰顯了其在理解多模態數據以及解決復雜視覺語言任務&#xff08;包括機器人操作任務&#xff09;方面的能力。我們致力于探尋一種簡便的方法&#xff0c;利用現有的視覺語言模型&#xff08;VLMs&#xff09;&#xff0c;僅…

zst-2001 上午題-歷年真題 算法(5個內容)

回溯 算法 - 第1題 找合適的位置&#xff0c;如果沒有位置就按B回家 d 分治 算法 - 第2題 b 算法 - 第3題 a 算法 - 第4題 劃分一般就是分治 a 算法 - 第5題 分治 a 0-1背包 算法 - 第6題 c 算法 - 第7題 最小的為c 3100 c 算法 - 第8題 …

淺論3DGS濺射模型在VR眼鏡上的應用

擺爛仙君小課堂開課了&#xff0c;本期將介紹如何手搓VR眼鏡&#xff0c;并將隨手拍的電影變成3D視頻。 一、3DGS模型介紹 3D 高斯模型是基于高斯函數構建的用于描述三維空間中數據分布概率的模型&#xff0c;高斯函數在數學和物理領域有著廣泛應用&#xff0c;其在 3D 情境下…

2025年中期大語言模型實力深度剖析

I. 引言&#xff1a;解讀2025年動態LLM競技場中的“實力” 用戶提出的“如今哪個大語言模型最強”這一問題&#xff0c;精準地反映了業界對飛速發展的人工智能&#xff08;AI&#xff09;領域的高度關注。本報告基于截至2025年5月的最新數據&#xff0c;旨在對這一問題進行全面…

Spark緩存-cache

一、RDD持久化 1.什么時候該使用持久化&#xff08;緩存&#xff09; 2. RDD cache & persist 緩存 3. RDD CheckPoint 檢查點 4. cache & persist & checkpoint 的特點和區別 特點 區別 二、cache & persist 的持久化級別及策略選擇 Spark的幾種持久化…

嵌入式開發學習日志(數據結構--順序結構單鏈表)Day19

一、順序結構 安裝軟件命令&#xff1a; sudo apt-get install (軟件名) 安裝格式化對齊&#xff1a;sudo apt-get install clang-format 內存泄漏檢測工具&#xff1a; sudo apt-get install valgrind 編譯后&#xff0c;使用命令 valgrind ./a.out 即可看內…

第六節第二部分:抽象類的應用-模板方法設計模式

模板方法設計模式的寫法 建議使用final關鍵字修飾模板方法 總結 代碼&#xff1a; People(父類抽象類) package com.Abstract3; public abstract class People {/*設計模板方法設計模式* 1.定義一個模板方法出來*/public final void write(){System.out.println("\t\t\t…

2025年滲透測試面試題總結-滲透測試紅隊面試三(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 滲透測試紅隊面試三 六十一、主機被入侵自查解決方案 六十二、NAT&#xff08;網絡地址轉換&#xff…

springboot-web基礎

21.web spring MVC 基于瀏覽器的 B/S 結構應用十分流行。Spring Boot 非常適合 Web 應用開發。可以使用嵌入式 Tomcat、Jetty、 Undertow 或 Netty 創建一個自包含的 HTTP 服務器。一個 Spring Boot 的 Web 應用能夠自己獨立運行&#xff0c;不依賴需 要安裝的 Tomcat&#x…

重構Cursor無限電子郵箱注冊系統的技術實踐

引言 在當今數字化時代&#xff0c;電子郵箱已成為個人和企業網絡身份的基礎。作為開發者&#xff0c;我們往往會遇到需要設計注冊系統的場景&#xff0c;而如何構建一個既安全又用戶友好的郵箱注冊系統&#xff0c;是值得深入探討的話題。本文將圍繞Cursor郵箱系統的技術重構…

2025.05.10京東機考真題算法崗-第三題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 03. 忍者屋頂之旅 問題描述 LYA是一位身手敏捷的忍者,正在一個古老的村莊進行飛檐走壁的訓練。村莊有兩排房屋,每排從左到右排列著 n n

vscode不能跳轉到同一個工作區的其他文件夾

明白了&#xff0c;你說的“第二種情況”是指&#xff1a; 你先打開的是項目文件夾&#xff08;比如 MyProject&#xff09;&#xff0c;然后通過 VS Code 的“添加文件夾到工作區”功能&#xff0c;把 ThirdPartyLib 文件夾添加進來。 結果&#xff0c;項目代碼里 #include “…

FastAPI 和 MongoDB 實現請求頭參數處理的示例,并在 React 中進行渲染

FastAPI 和 MongoDB 后端 安裝必要的庫 安裝 FastAPI、Uvicorn、Motor&#xff08;用于 MongoDB 的異步驅動&#xff09;和 Pydantic&#xff08;用于數據驗證&#xff09;。 pip install fastapi uvicorn motor pydantic創建 FastAPI 應用 創建一個文件 main.py&#xff0c;并…

技術倫理雙軌認證如何重構AI工程師能力評估體系——基于AAIA框架的技術解析與行業實證研究

引言&#xff1a;AI工程師能力評估的范式轉型 2025年全球人工智能產業呈現出兩大特征&#xff1a;技術迭代加速與監管框架完善。據Gartner數據顯示&#xff0c;全球75%的企業在AI項目部署中遭遇技術倫理混合型難題&#xff0c;傳統單維度技術認證體系已無法滿足產業需求。本文…

03.Golang 切片(slice)源碼分析(二、append實現)

Golang 切片&#xff08;slice&#xff09;源碼分析&#xff08;二、append實現&#xff09; 前言&#xff1a; Golang 切片&#xff08;slice&#xff09;源碼分析&#xff08;一、定義與基礎操作實現&#xff09; 在前面的文章我們介紹了&#xff0c;切片的結構體與創建\擴容…

mysql常用方法

mysql常用方法 一、基本用法 -- MySQL創建唯一索引 CREATE UNIQUE INDEX 索引名 ON 表名(列名1,列名2,...); --也可以使用ALTER TABLE語句給現有表添加唯一索引&#xff08;UNIQUE&#xff09; ALTER TABLE 表名 ADD CONSTRAINT 索引名 UNIQUE KEY(列名1,列名2,...); alter t…

STM32F103C8T6板子使用說明

第一章 計算機體系結構(了解) 后續在板子上開發的時候&#xff0c;需要考慮是否有操作系統 方式一&#xff1a;有操作系統&#xff0c;通過c庫通過os api操作硬件方式二&#xff1a;無操作系統&#xff0c; 通過c庫通過固件庫操作硬件 第二章 STM32開發板概述 板子/開發板&…

PBR材質-Unity/Blender/UE

目錄 前言&#xff1a; 一、Unity&#xff1a; 二、Blender&#xff1a; 三、UE&#xff1a; 四、全家福&#xff1a; 五、后記&#xff1a; 前言&#xff1a; PBR流程作為表達物理效果的經典方式&#xff0c;很值得一學。紋理貼圖使用的是上一期的Textures | cgbookcas…

【生產實踐】Linux中/usr/bin、/usr/sbin與/usr/local的關系解析(2025年技術規范)

一、核心定位與功能劃分 /usr/bin&#xff1a;用戶級通用命令庫 ? 定位&#xff1a;存儲系統預裝的用戶級可執行文件&#xff0c;這些命令通常由Linux發行版官方軟件包管理器&#xff08;如APT、YUM&#xff09;安裝&#xff0c;屬于系統默認功能的一部分。 ? 示例命令&#…