leetcode211 一点心得

这个题目跟208相似,但是其中有一个细节需要注意,让我纠结了半天。

#include<iostream>
#include<cstring>
#include<string>

using namespace std;

class DictNode{
public:
    char c;
    DictNode* next[26];
    bool isWord;
    DictNode(char _c):c(_c),isWord(false){
        memset(next,0,sizeof(DictNode*) * 26);        
    }
    DictNode():isWord(false){
        memset(next,0,sizeof(DictNode*) * 26);
    }
};


class WordDictionary {
public:
    //constructor
    WordDictionary(){
        root = new DictNode();
    }
    // Adds a word into the data structure.
    void addWord(string word) {
        DictNode* p = root;
        for(int i = 0 ; i < word.size() ; ++i ){
            char c = word[i];
            int idx = c - 'a';
            if(!p->next[idx]){
                p->next[idx] = new DictNode(c);
            }
            p = p -> next[idx];
        }
        p->isWord = true;
    }

    // Returns if the word is in the data structure. A word could
    // contain the dot character '.' to represent any one letter.
    bool search(string word) {
        return searchHelper(root,word.c_str());
    }
private:
    DictNode* root;

    bool searchHelper(DictNode* now,const char* s){
        DictNode* p =now;
        for(int i = 0; i < strlen(s); ++i){
            if(p && s[i] == '.'){
                DictNode* x = p;    //*
                for(int j = 0;j < 26 ; ++j){
                    p = x->next[j]; //*
                    if(searchHelper(p,s+i+1)) return true;//*

                    //DictNode* x = p->next[j];
                    //if(searchHelper(x,s+i+1)) return true;
                }
            }else if(p && s[i] != '.'){
                int idx = s[i] - 'a';
                p = p -> next[idx];
            }else{
                break;
            }
        }
        return p && p->isWord;
    }
};

// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary;
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");

int main(){
    WordDictionary wordDictionary;
    wordDictionary.addWord("a");
    bool t = wordDictionary.search("a.");
    cout<< t << endl;
}

注意带//*号附近的代码

DictNode* x = p;//*
for(int j = 0;j < 26 ; ++j){
   p = x->next[j]; //*
   if(searchHelper(p,s+i+1)) return true;//*

   //DictNode* x = p->next[j];
   //if(searchHelper(x,s+i+1)) return true;

如果将带星号的代码行去掉,将后两行的注释去掉,那么好像代码也没有问题,都是在这个地方需要遍历p节点的next数组,但是后面的两行其实是不正确的!
原因在于,星号行的代码执行后,p就被改变了,但是写成最后两行的样式,那么p是无论如何不会改变的,这样的话,字典树的整个遍历就在这个地方卡住了,如果字典中有”a”,而待查找的字符串为”a.”,那么用最后两行的写法就会输出true,但是明显应该是false,长度都不同。
果然自己还是渣,慢慢练吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值