Every day a Leetcode
题目来源:3045. 统计前后缀下标对 II
解法1:字典树

将这个列表哈希化:idx = (s[i] - ‘a’) * 26 + (s[j] - ‘a’)。
枚举 t=words[j],怎么统计有多少个 s=words[i] 是 t 的前缀?
这可以用字典树解决,在遍历 words 的同时,维护每个字符串的出现次数。当我们遍历 t 时,同时遍历字典树上的对应节点,并把 t 插入字典树。
代码:
/*
* @lc app=leetcode.cn id=3045 lang=cpp
*
* [3045] 统计前后缀下标对 II
*/
// @lc code=start
// 字典树
class Solution
{
public:
struct Trie
{
unordered_map<int, Trie *> childs;
int cnt = 0;
};
Trie *trie = new Trie();
void add(const string &s)
{
Trie *cur = trie;
int n = s.size();
for (int i = 0, j = n - 1; i < n; ++i, --j)
{
int idx = (s[i] - 'a') * 26 + (s[j] - 'a');
if (!cur->childs.count(idx))
{
cur->childs[idx] = new Trie();
}
cur = cur->childs[idx];
cur->cnt += 1;
}
}
int query(const string &s)
{
Trie *cur = trie;
int n = s.size();
for (int i = 0, j = n - 1; i < n; ++i, --j)
{
int idx = (s[i] - 'a') * 26 + (s[j] - 'a');
if (!cur->childs.count(idx))
return 0;
cur = cur->childs[idx];
}
return cur->cnt;
}
long long countPrefixSuffixPairs(vector<string> &words)
{
int n = words.size();
long long ans = 0;
for (int i = n - 1; i >= 0; --i)
{
ans += query(words[i]);
add(words[i]);
}
return ans;
}
};
// @lc code=end
结果:

复杂度分析:
时间复杂度:O(L),其中 L 为所有 words[i] 的长度之和。
空间复杂度:O(L),其中 L 为所有 words[i] 的长度之和。
![[Flutter]设置应用包名、名称、版本号、最低支持版本、Icon、启动页以及环境判断、平台判断和打包](https://img-blog.csdnimg.cn/direct/7949861475f24fb49d880e1737da4f66.png)
![[Mac软件]Adobe Substance 3D Stager 2.1.4 3D场景搭建工具](https://img-blog.csdnimg.cn/img_convert/43e1e340d57b052e19205822f8611f47.png)
















