天天写算法之Hat’s Words

本文介绍了一种使用字典树来判断一个字符串是否能由两个已知字符串组成的算法。该方法通过构建字典树来快速查找子串,避免了使用并查集带来的复杂度问题。

点击打开链接

题目大概的意思是:

输入一堆字符串,判断哪些字符串可以由其他两方字符串组成。

一开始我想到的是并查集,但后来仔细想了想后,发现并查集,处理连续不连续问题的时候只适合区间问题。就是【5  7】这种类型的,我要是想解决字母问题的话,我就得把char一个个存进去,然后来了新的以后,判断是不是共同的parent,但是这个时候问题就又来了,即使是共同的parent,还需要更加细致的判断才可以说明组成问题。需要多加几个标记,比如头标记,尾标记。但是我没有尝试,还是用的字典树解决的这个问题。感觉复杂度有点高。n的三次方级别???

#include <iostream>
#include <cstdio>
#include <cstring>
#include<malloc.h>
#define MAX 3111
using namespace std;

struct Node{
    char *res ;
    Node* next[26];
    bool flag ;
    Node(){
    for(int i =0 ; i < 26; i++)
        next[i]=NULL;
    flag = false ;
    }

};
Node *p,*root = new Node() ;
void Insert(char *target)
{
        p = root ;
        for(int i = 0 ; i < strlen(target);i++)
        {
            int temp = target[i] -'a' ;
            if(p->next[temp]==NULL)
            {
                p->next[temp] = new Node();
            }
            p = p->next[temp];
        }
        p->flag = true ;
}

bool Search(char *target)
{
    p = root ;
    for(int i = 0 ; i < strlen(target);i++)
    {
        int temp = target[i]-'a';
        if(p->next[temp]==NULL)
            return false ;
        p=p->next[temp];
    }
    return p->flag ;

}
char ss[50001][51];
int main()
{
    int cnt = 0 ;
    while(~scanf("%s",&ss[cnt++]))
    {
        Insert(ss[cnt-1]);
    }


    for(int i = 0 ; i <cnt ; i ++)
    {
        int len = strlen(ss[i]);
        for(int j = 1 ; j <len ; j++)
        {
                char s1[50] = {'\0'} ,s2[50]={'\0'};
                strncpy(s1,ss[i],j);
                strncpy(s2,ss[i]+j,len-j);
            if(Search(s1)&&Search(s2))
            {
                printf("%s\n",ss[i]);
                break ;
            }
        }
    }
    return 0 ;


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值