leetcode面试150题day03

一、字典树(Trie)

class Trie 
{
private:
    vector<Trie*> children;
    bool isEnd;
public: 
    Trie():children(26,nullptr),isEnd(false){}
    ~Trie()
    {
        for (Trie* child : children)
        {
            if (child)delete child;
        }
    }   
    void insert(string word) 
    {
        Trie* p = this;
        for (char ch : word)
        {
            if (!p->children[ch - 'a']) p->children[ch - 'a'] = new Trie();
            p = p->children[ch - 'a'];
        }
        p->isEnd = true;
    }

    bool search(string word) 
    {
        Trie* p = this;
        for (char ch : word)
        {
            if (!p->children[ch - 'a']) return false;
            p = p->children[ch - 'a'];
        }
        return p->isEnd;
    }

    bool startsWith(string prefix) 
    {
        Trie* p = this;
        for (char ch : prefix)
        {
            if (!p->children[ch - 'a']) return false;
            p = p->children[ch - 'a'];
        }
        return true;
    }
};

二、前缀('.')匹配的字典树

 class TrieNode
    {
    public:
        vector<TrieNode*> children;
        bool isWord;
        //表示每一个节点的子结点都是26个字符组成
        TrieNode() :children(26, nullptr), isWord(false) {};

        //手动释放内存,Vector不能自动释放指针,只能自动释放对象
        ~TrieNode()
        {
            for (TrieNode* child : children)
            {
                if (child)
                    delete child;
            }
        }
    };
    class WordDictionary
    {
    public:
        WordDictionary()
        {
            root = new TrieNode();
        }
        ~WordDictionary()
        {
            delete root;
        }

        void addWord(string word)
        {
            TrieNode* p = root;
            for (char ch : word)
            {
                //如果在该节点的children中没有这个字符ch就新建一个节点
                //因为children代表的是子树的26个字符的指针的数组(Vector)
                //所以索引就是ch-'a'的大小
                if (!p->children[ch - 'a'])
                    p->children[ch - 'a'] = new TrieNode();
                //有这个字符就将p移动到该字符
                p = p->children[ch - 'a'];
            }
            //插入单词结束后标记当前节点为单词的结尾
            p->isWord = true;
        }

        bool search(string word)
        {
            TrieNode* p = root;
            //index表示从字符串的第一个字符开始匹配搜索,表示的是字符串中的字符索引从0开始
            int index = 0;
            return searchHelper(word, index, p);
        }

        bool searchHelper(const std::string& word, int index, TrieNode* node)
        {
            //如果字符串中的每一个字符都比较之后
            if (index == word.size())
                return node->isWord;
            //这里取出每个索引对应的字符值进行比较
            char ch = word[index];
            // 如果没有通配符 '.', 则递归搜索相应字符的子节点
            if (ch != '.')
            {
                TrieNode* child = node->children[ch - 'a'];
                return child && searchHelper(word, index + 1, child);
            }
            else// 如果遇到通配符 '.', 则递归搜索所有子节点
            {
                for (TrieNode* child : node->children)
                {
                    if (child && searchHelper(word, index + 1, child))
                        return true;
                }
            }
            return false;

        }
    private:
        TrieNode* root;
    };

四、只出现一次的数字(位的异或运算)

class Solution 
{
public:
    int singleNumber(vector<int>& nums) 
    {
        int res = 0;
        for (int num : nums)
        {
            res = res ^ num;
        }
        return res;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值