127. 单词接龙;131. 分割回文串

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:


    每次转换只能改变一个字母。
    转换过程中的中间单词必须是字典中的单词。


说明:


    如果不存在这样的转换序列,返回 0。
    所有单词具有相同的长度。
    所有单词只由小写字母组成。
    字典中不存在重复的单词。
    你可以假设 beginWord 和 endWord 是非空的,且二者不相同。


示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。


示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

class tire{
    bool isWord;
    unordered_map<char,tire*>next;
public:
    tire():isWord(false){
        for(char i='a';i<='z';++i)
            next[i]=nullptr;
    }
    void insertWord(string s){
        tire *cur=this;
        for(int i=0;i<s.size();++i)
            if(cur->next[s[i]])
                cur=cur->next[s[i]];            
            else{
                tire *temp=new tire();
                cur->next[s[i]]=temp;
                cur=temp;
            }
        cur->isWord=true;
    }
    bool hasWord(string s){
        tire *cur=this;
        for(int i=0;i<s.size();++i){
            if(!cur->next[s[i]])return false;
            cur=cur->next[s[i]];
        }
        return cur->isWord;
    }
    void findNeighber(string s,vector<string>& vec){
        tire *cur=this;
        for(int i=0;i<s.size();++i){
            for(char c='a';c<='z';++c){
                if(c==s[i])continue;
                if(cur->next[c]&&cur->next[c]->hasWord(s.substr(i+1))){
                    string temp=s;
                    temp[i]=c;
                    vec.push_back(temp);
                }
            }
            cur=cur->next[s[i]];
        }
    }
};
class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        if(beginWord.size()==0||beginWord.size()!=endWord.size())return 0;
        int resCnt=1;
        tire *allWord=new tire(),*visited=new tire();
        allWord->insertWord(beginWord);
        for(int i=0;i<wordList.size();++i)
            allWord->insertWord(wordList[i]);
        if(!allWord->hasWord(endWord))return 0;
        queue<string>q;
        q.push(beginWord);
        while(q.size()){
            int qSize=q.size();
            ++resCnt;
            while(qSize--){
                string temp=q.front();
                q.pop();
                vector<string>vec;                
                allWord->findNeighber(temp,vec);
                for(int i=0;i<vec.size();++i){
                    if(visited->hasWord(vec[i]))continue;
                    if(vec[i]==endWord)return resCnt;
                    q.push(vec[i]);
                    visited->insertWord(vec[i]);                    
                }
            }
        }
        return 0;
    }
};

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

输入: "aab"
输出:
[
  ["aa","b"],
  ["a","a","b"]
]

class Solution {
    vector<vector<string>> res;
    vector<string>path;
    string sel;
public:
    vector<vector<string>> partition(string s) {
        if(s.size()<1)return {};
        sel=s;
        backTrack(0);
        return res;
    }
    bool isOrNot(int start,int end){
        while(start<end)
            if(sel[start++]!=sel[end--])return false;
        return true;
    }
    void backTrack(int start){
        if(start==sel.size()){
            res.push_back(path);
            return;
        }
        for(int i=start;i<sel.size();++i){
            if(isOrNot(start,i)){
                path.push_back(sel.substr(start,i-start+1));
                backTrack(i+1);
                path.pop_back();
            }
        }
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值