【数据结构】刷题记录【字典树】

简介: 【数据结构】刷题记录【字典树】

AcWing 124 前缀统计

解题思路: 因为查询的是前缀,只需要将单词中的每个字母的cnt相加即可

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
int son[maxn][26],cnt[maxn],idx;
char str[maxn];
void add(char *str){
    int p=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u]) son[p][u]=++idx;
        p=son[p][u];
    }
    cnt[p]++;
}
int ask(char *str){
    int p=0,res=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u]) break;
        p=son[p][u];
        res+=cnt[p];
    }
    return res;
}
void AC(){
    int n,m;
    cin>>n>>m;
    while(n--){
        cin>>str;
        add(str);
    }
    while(m--){
        cin>>str;
        cout<<ask(str)<<endl;
    }
}
int main(){
    AC();
    return 0;
}

AcWing 835. Trie字符串统计

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int son[N][26],cnt[N],idx;
char str[N];
void insert(char *str){
    int p=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u]) son[p][u]=++idx;
        p=son[p][u];
    }
    cnt[p]++;
}
int query(char *str){
    int p=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u]) return 0;
        p=son[p][u];
    }
    return cnt[p];
}
int main(){
    int n;
    cin>>n;
    while(n--){
        char op[2];
        scanf("%s%s",op,str);
        if(*op=='I') insert(str);
        else printf("%d\n",query(str));
    }
    return 0;
}

AcWing 143. 最大异或对

解题思路: 有点贪心的感觉,我们每一次都走与当前这一位相反的位置,也就是让异或值最大,如果说没有相反的位置可以走的话,那么就走相同的位置.

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 100010, M = 3000000;
int n;
int a[N], son[M][2], idx;
void insert(int x)
{
    int p = 0;
    for (int i = 30; i >= 0; i -- )
    {
        int &s = son[p][x >> i & 1];
        if (!s) s = ++ idx;
        p = s;
    }
}
int search(int x)
{
    int p = 0, res = 0;
    for (int i = 30; i >= 0; i -- )
    {
        int s = x >> i & 1;
        if (son[p][!s])
        {
            res += 1 << i;
            p = son[p][!s];
        }
        else p = son[p][s];
    }
    return res;
}
int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ )
    {
        scanf("%d", &a[i]);
        insert(a[i]);
    }
    int res = 0;
    for (int i = 0; i < n; i ++ ) res = max(res, search(a[i]));
    printf("%d\n", res);
    return 0;
}

AcWing161. 电话列表

思路: 满足答案的关系只有两种,一种是插入的串是之前的串的前缀,那么只要看在插入过程中是不是没有新增节点;另一种是插入的串包括之前的串,也就是之前的串是插入的串的前缀,这个只要看看有没有走到打了标记的点就好了。所以只需要在插入时判断即可;

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
int son[maxn][10],cnt[maxn],idx;
char str[maxn];
int add(char *str){
    int p=0,f1=0,f2=1;
    for(int i=0;str[i];i++){
        int u=str[i]-'0';
        if(!son[p][u]) son[p][u]=++idx,f2=0;
        p=son[p][u];
        if(cnt[p]) f1=1;
    }
    cnt[p]=1;
    if(f1||f2) return 1;
    return 0;
}
void AC(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        idx=0;
        memset(son,0,sizeof son);
        memset(cnt,0,sizeof cnt);
        bool flag=true;
        while(n--){
            cin>>str;
            if(add(str)) flag=false;
        }
        if(flag) puts("YES");
        else puts("NO");
    }
}
int main(){
    AC();
    return 0;
}

未完待续

待刷题目合集:字典树题目 - Virtual Judge

密码:ludicpc

参考博客:AcWing 161. 电话列表 - AcWing

字典树题目总结_天亮说晚安-CSDN博客

目录
相关文章
|
8月前
|
算法
【数据结构与算法 刷题系列】求带环链表的入环节点(图文详解)
【数据结构与算法 刷题系列】求带环链表的入环节点(图文详解)
|
8月前
|
算法
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
|
8月前
|
算法
【数据结构与算法 刷题系列】移除链表元素
【数据结构与算法 刷题系列】移除链表元素
|
8月前
|
存储 算法 C语言
【数据结构与算法 刷题系列】合并两个有序链表
【数据结构与算法 刷题系列】合并两个有序链表
|
8月前
|
存储 算法 C语言
【数据结构与算法 刷题系列】环形链表的约瑟夫问题
【数据结构与算法 刷题系列】环形链表的约瑟夫问题
|
8月前
|
算法 C语言
【数据结构与算法 刷题系列】求链表的中间结点
【数据结构与算法 刷题系列】求链表的中间结点
|
8月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
8月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
9月前
|
Java
JAVA数据结构刷题 -- 二叉树进阶
JAVA数据结构刷题 -- 二叉树进阶
57 0
|
9月前
|
存储 Java
JAVA数据结构刷题 -- 力扣二叉树
JAVA数据结构刷题 -- 力扣二叉树
68 0

热门文章

最新文章