力扣:1455. 检查单词是否为句中其他单词的前缀

126 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

1455. 检查单词是否为句中其他单词的前缀

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

 

示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet""code" 拼接成。

示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。
     
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

 提示:

  • 1 <= sentence.length <= 100
  • 1 <= searchWord.length <= 10
  • sentence 由小写英文字母和空格组成。
  • searchWord 由小写英文字母组成。

问题解析

暴力做法

先创建一个字符串s,for循环取出所有的单次:如果当前字符不是空格,就把字符加到s后面,如果是空格说明s已经是一个单词了,我们拿这个单词去判断searchWord是否是它的前缀,判断完后把s清空。

设searchWord的长度为len,for循环遍历字符串searchWord,对于s的前len个字符与searchWord相等,我们则说searchWord是当前单词s的前缀,返回当前单词在原字符串的次序即可。

AC代码

const int N=200;
class Solution {
public:
    bool check(string a,string b)
    {
        if(a.size()<b.size())return false;
        int n=b.size();
        for(int i=0;i<n;i++)
        {
            if(a[i]!=b[i])return false;
        }
        return true;
    }
    int isPrefixOfWord(string sentence, string searchWord) {
        sentence+=" ";
        int n=sentence.size(),cnt=1;
        string s;
        for(int i=0;i<n;i++)
        {
            if(sentence[i]!=' ')s+=sentence[i];
            else 
            {
                if(check(s,searchWord))return cnt;
                cnt++;
                s.clear();
            }
        }
        return -1;
    }
};

字典树

我们求出每个单词s后,可以把它插入字典树f中,这样我们只要最后在字典树上进行一次查询,即可知道searchWord是否是某个单词的前缀。

(具体看代码)

AC代码

const int N=200;
class Solution {
public:
    //f是字典树,cnt[i]是判断字典树中是否有以i结尾的字符串(初始为0),ans是说明当前插入的单词是第几个
    int f[N][26],cnt[N],idx=1,ans=1;
    //将单词插入字典树
    void insert(string s)
    {
        int p=1;
        for(auto i:s)
        {
            int j=i-'a';
            //如果当前字典树没有这个分支,则新创一个分支
            if(f[p][j]==0)
            {
                f[p][j]=++idx;
                //将ans赋给cnt[p],说明以当前字符串为结尾的单词是第ans个单词
                if(cnt[p]==0)cnt[p]=ans;
                else cnt[p]=min(cnt[p],ans);
            }
            p=f[p][j];
        }
        //单词次序++
        cnt[p]=ans++;
    }
    //在字典树上查询
    int query(string s)
    {
        int p=1;
        for(auto i:s)
        {
            int j=i-'a';
            //如果没有出现当前分支,说明searchWord没有出现过,返回-1
            if(f[p][j]==0)return -1;
            p=f[p][j];
        }
        return cnt[p]==0?-1:cnt[p];
    }
    int isPrefixOfWord(string sentence, string searchWord) {
        sentence+=" ";
        int n=sentence.size();
        string s;
        for(int i=0;i<n;i++)
        {
            if(sentence[i]!=' ')s+=sentence[i];
            else 
            {
                //在字典树上插入当前单词
                insert(s);
                s.clear();
            }
        }
        return query(searchWord);
    }
};