20.8.8 Trie(前缀树) 环形链表环的起点

1.Trie(不是二叉树)

Trie 树是一个有根的树,其结点具有以下字段:

最多 RR 个指向子结点的链接,其中每个链接对应字母表数据集中的一个字母。
布尔字段,以指定节点是对应键的结尾还是只是键前缀。

在这里插入图片描述

其他人写的正常版本

class Trie {
private:
    Trie* child[26];
    bool isword;
public:
    /** Initialize your data structure here. */
    Trie() {
        isword=false;
        for(int i=0;i<26;i++)
            child[i]=nullptr;
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* trie=this;
        for(char& c:word){
            int id=c-'a';
            if(!trie->child[id]) trie->child[id]=new Trie();
            trie=trie->child[id];
        }
        
        trie->isword=true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* trie=this;
        for(auto& c:word){
            int id=c-'a';
            if(!trie->child[id]) return false;
            trie=trie->child[id];
        }
        
        return trie->isword;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* trie=this;
        for(auto& c:prefix){
            int id=c-'a';
            if(!trie->child[id]) return false;
            trie=trie->child[id];
        }
        return true;
    }
};

自己写的hashmap版本

class Trie {
private:
    bool isend;
    unordered_map<char,Trie*> um;
public:
    /** Initialize your data structure here. */
    Trie() {
        isend=false;
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* temp=this;
        for(auto s:word){
            if(temp->um.find(s)==temp->um.end())temp->um[s]=new Trie();
            temp=temp->um[s];
        }
        temp->isend=true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* temp=this;
        for(auto s:word){
            if(temp->um.find(s)==temp->um.end()) return false;
            temp=temp->um[s];
        }
        return temp->isend;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* temp=this;
        for(auto s:prefix){
            if(temp->um.find(s)==temp->um.end()) return false;
            temp=temp->um[s];
        }
        return true;
    }
};

2.环形链表的环的起点

原题

使用了快慢指针:

fast和slow的起点都是head
如果指针遇到了null则说明链表没有环,返回null
fast每次走两步,slow每次走一步,若有环,则fast在超过slow若干圈后一定会和slow相遇
两个指针第一次相遇时,设slow经过的长度是k,则fast经过了2k,环的长度为2k-k=k
再设链表头距离环的起点的长度为x,相遇点距离环的起点的长度为m
slow跑过的长度k=x+m,则x=k-m
而fast在当前圈已经跑了m,再跑k-m再次到达环的起点(环的长度为k)
所以将slow放回起点,它和fast每次都只走一步,经过k-m距离,恰好在环的起点相遇
 ListNode *detectCycle(ListNode *head) {
        ListNode* slow=head;
        ListNode* fast=head;
        do{
            if(fast==nullptr||fast->next==nullptr) return nullptr;
            slow=slow->next;
            fast=fast->next->next;           
        }while(slow!=fast);
        slow=head;
        while(slow!=fast){
            slow=slow->next;
            fast=fast->next;
        }
        return fast;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值