当前位置: 首页 > news >正文

7.20 树hash |字典树模板❗

 

 

字典树模板2.0

 struct Node {
Node* son[26]{};
bool end = false;
};

class Trie {
Node* root = new Node();

 

 

 int find(string word)

   {
Node* cur = root;
for (char c : word)

     {
c -= 'a';
if (cur->son[c] == nullptr)

            { // 道不同,不相为谋
return 0;

}
cur = cur->son[c];
}
// 走过同样的路(2=完全匹配,1=前缀匹配)
return cur->end ? 2 : 1;
}

 

 

 

    void destroy(Node* node) {
if (node == nullptr) {
return;
}
for (Node* son : node->son) {
destroy(son);
}
delete node;
}

public:
~Trie() {
destroy(root);
}

    void insert(string word)

{
Node* cur = root;
for (char c : word)

        {
c -= 'a';
if (cur->son[c] == nullptr)

           {   // 无路可走?
cur->son[c] = new Node();

                 // new 出来!
}
cur = cur->son[c];
}
cur->end = true;
}

 

 

    bool search(string word) {
return find(word) == 2;
}

    bool startsWith(string prefix) {
return find(prefix) != 0;
}
};

 

 

旋转矩阵

 class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n / 2; i++)

     {
for (int j = 0; j < (n + 1) / 2; j++)

          {
int tmp = matrix[i][j];
matrix[i][j] = matrix[n - 1 - j][i];
matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j];
matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];
matrix[j][n - 1 - i] = tmp;
}
}
}
};

 

 

 

字典树

 

 

// 字典树节点结构体
struct TrieNode {
unordered_map<char, TrieNode*> children;
bool is_end_of_word;
TrieNode() : is_end_of_word(false) {}
};

 

// 字典树类
class Trie {
private:
TrieNode* root;

 

    // 辅助函数,用于查找前缀对应的节点
TrieNode* searchPrefix(const string& prefix) {
TrieNode* node = root;
for (char c : prefix)

    {
if (node->children.find(c) == node->children.end())

           {
return nullptr;
}
node = node->children[c];
}
return node;
}

public:


// 构造函数,初始化根节点
Trie() {
root = new TrieNode();
}

 

    // 插入单词到字典树
void insert(const string& word) {
TrieNode* node = root;
for (char c : word)

{
if (node->children.find(c) == node->children.end())

       {
node->children[c] = new TrieNode();
}

node = node->children[c];
}
node->is_end_of_word = true;
}

 

    // 查找单词是否在字典树中(完整存在)
bool search(const string& word)

{
TrieNode* node = searchPrefix(word);
return node != nullptr && node->is_end_of_word;
}

 

    // 查找是否有单词以给定前缀开头
bool startsWith(const string& prefix)

    {
return searchPrefix(prefix) != nullptr;
}
};

 

 

 

lc1948.树hash

 

#define ull unsigned long long
class Solution

{
const int base = 31;


struct Node

        {
string name;
Node(string name) {
this->name = name;
}
};


public:
vector<vector<string>> deleteDuplicateFolder(vector<vector<string>>& paths)

{
vector<vector<string>> ans;
unordered_map<Node*, map<string, Node*>> mp;
unordered_map<Node*, Node*> fa;


Node* root = new Node("");
for (const auto& v: paths)

       {
Node* last = root;
for (const auto& s: v)

       {
if (mp[last].count(s) == 0)

              {
Node* tmp = new Node(s);
mp[last][s] = tmp;
fa[tmp] = last;
last = tmp;
}
else last = mp[last][s];
}
}


map<ull, vector<Node*>> del;


function<ull(Node*)> dfs = [&](Node* node) {
// 如果没有子节点,直接返回哈希值
if (mp.count(node) == 0 || mp[node].size() == 0) {
ull H = 0;
for (const auto& c: node->name) {
H *= base;
H += c;
}
return H;
}


ull H = 0;
// 遍历所有子节点,计算哈希值,加在一起
for (const auto& ss: mp[node]) {
H += 71 * dfs(ss.second);
}
// 存储子树的哈希值
del[H].push_back(node);
// 加上自己的节点哈希值,返回
for (const auto& c: node->name) {
H += c;
}
return H;
};


dfs(root);
for (const auto& p: del) {
if (p.second.size() > 1) {
for (const auto& ss: p.second) {
mp[fa[ss]].erase(ss->name);
}
}
}


function<void(Node*, vector<string>&)> cal = [&](Node* node, vector<string>& rec) {
for (const auto& ss: mp[node]) {
rec.push_back(ss.first);
ans.push_back(rec);
cal(ss.second, rec);
rec.pop_back();
}
};


vector<string> rr;
cal(root, rr);
return ans;
}
};

 

删除文件夹路径中的重复子文件夹,通俗来说就是:如果两个文件夹的子结构完全相同(包含的子文件夹和文件结构一样),就把它们都删掉,最后返回剩下的有效路径。

具体实现思路可以分3步:

1. 构建文件夹结构树

- 把输入的所有路径(比如 ["a","b"] 、 ["a","c"] )转换成一棵“文件夹树”
- 每个节点代表一个文件夹,节点之间的父子关系对应路径中的层级(比如 a 是 b 的父节点)

2. 找出重复的子文件夹

- 用哈希值表示每个文件夹的“子结构”:
- 空文件夹(没有子文件夹):哈希值只由自身名字计算
- 有子文件夹的:哈希值由所有子文件夹的哈希值组合而成(相当于给整个子结构“签名”)
- 哈希值相同的文件夹,说明它们的子结构完全重复,标记这些文件夹要删除

3. 删除重复文件夹并输出结果

- 把标记为重复的文件夹从树上删掉(连带它们的子文件夹一起删)
- 遍历剩下的树,收集所有完整路径,就是最终结果


举个例子:
如果输入路径有 ["a","x"] 和 ["b","x"] ,这两个 x 文件夹都是空的(子结构相同),会被判定为重复并删除,最终结果就是空;
如果输入 ["a","b"] 和 ["a","c"] ,两个子文件夹结构不同,就都会保留。

 

http://www.dtcms.com/a/289697.html

相关文章:

  • LangChain4j多模型共存+整合SpringBoot
  • springboot websocket 自动重启方案
  • SpringBoot3集成MapstructPlus
  • 抓包工具使用教程
  • 网安-文件上传-upload-labs
  • Laravel 原子锁概念讲解
  • jdk各个版本特性
  • Linux 基础文件IO操作
  • 零基础学习性能测试第一章:核心性能指标-并发量
  • Node.js 中基于请求 ID 实现简单队列(即时阻止策略/排队等待策略)
  • DMZ网络
  • (1)Windows环境下安装Oracle
  • Vue3 Proxy 数据劫持为什么比Object.defineProperty() Vue2数据劫持的性能更好
  • 人工智能训练师三级实操题第一部分数据处理
  • shell 脚本基础学习
  • Java中的intern()方法
  • 全新安装Proxmox VE启动时卡在Loading initial ramdisk
  • RAII机制以及在ROS的NodeHandler中的实现
  • 【c++】200*200 01灰度矩阵求所有的连通区域坐标集合
  • 鸿蒙开发中 渲染范围的控制
  • 飞腾D2000的BIOS编译
  • 在服务器无网络的环境下安装 VS Code Remote-SSH 组件
  • 【Python练习】053. 编写一个函数,实现简单的文件加密和解密功能
  • C++string类(3)
  • 基于单片机的火灾报警系统设计
  • SaTokenException: 未能获取对应StpLogic 问题解决
  • c#转python第四天:生态系统与常用库
  • 新版Acrobat Pro DC 2025 PDF编辑器下载与保姆级安装教程!!
  • Mermaid 语法
  • 突破select瓶颈:深入理解poll I/O复用技术