HDU1671——前缀树的一点感触

题目http://acm.hdu.edu.cn/showproblem.php?pid=1671

题目本身不难,一棵前缀树OK,但是前两次提交都没有成功。

第一次Memory Limit Exceeded

前缀树是很费空间的数据结构,每个节点存放了字母(数字)个数个指针,正所谓用空间来换取时间。

我发现我忘记写析构函数了,所以测例多起来还不释放很容易超空间。

树形结构的析构也很有趣:

复制代码
 1 ~Node()
 2 {
 3     for (int i = 0; i < 10; ++i)
 4     {
 5         if (children[i])
 6         {
 7             delete children[i];
 8             children[i] = nullptr;
 9         }
10     }
11 }
复制代码

好了,第二次没成功,Time Limit Exceeded

看起来这是一棵规规矩矩的前缀树,仔细找可以优化的地方,试探性地把

1 vector<Node *> children;
2 Node()
3 {
4     for (int i = 0; i < 10; ++i) children.push_back(nullptr);
5 }

改成了

1 vector<Node *> children = vector<Node *>(10, nullptr);
2 Node()
3 {
4     //for (int i = 0; i < 10; ++i) children.push_back(nullptr);
5 }

Accepted!显然构造的时候赋值比构造之后再赋值要快。。果然还是要尽可能的优化啊!

附代码:

复制代码
 1 #include <string>
 2 #include <vector>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 class Node
 8 {
 9 public:
10     bool is_phone = false;
11     vector<Node *> children = vector<Node *>(10, nullptr);
12     Node()
13     {}
14     ~Node()
15     {
16         for (int i = 0; i < 10; ++i)
17         {
18             if (children[i])
19             {
20                 delete children[i];
21                 children[i] = nullptr;
22             }
23         }
24     }
25     void insert(const string &_Phone)
26     {
27         Node *p = this;
28         for (int i = 0; i < _Phone.size(); ++i)
29         {
30             int curr = _Phone[i] - '0';
31             if (p->children[curr] == nullptr)
32             {
33                 p->children[curr] = new Node();
34             }
35             p = p->children[curr];
36         }
37         p->is_phone = true;
38     }
39     bool has_phone(const string &_Phone)
40     {
41         Node *p = this;
42         for (int i = 0; i < _Phone.size(); ++i)
43         {
44             int curr = _Phone[i] - '0';
45             if (!p->children[curr]) return false;
46             if (p->children[curr]->is_phone) return true;
47             p = p->children[curr];
48         }
49         return true;
50     }
51 };
52 
53 typedef Node *Trie;
54 
55 int main()
56 {
57     int t;
58     cin >> t;
59     while (t--)
60     {
61         Trie trie = new Node();
62         int n;
63         cin >> n;
64         string phone;
65         bool flag = true;
66         while (n--)
67         {
68             cin >> phone;
69             if (trie->has_phone(phone)) { flag = false; }
70             trie->insert(phone);
71         }
72         if (flag) cout << "YES" << endl;
73         else cout << "NO" << endl;
74         delete trie;
75     }
76     //system("pause");
77     return 0;
78 }
复制代码

 

posted @   jily16  阅读(238)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示