bool buildTree(unordered_set<string> &forward, unordered_set<string> &backward, unordered_set<string> &dict, 
 unordered_map<string, vector<string>> &tree, bool reversed){
       if (forward.empty())
             return false;
       if (forward.size() > backward.size())
       	return buildTree(backward, forward, dict, tree, !reversed);
       for (auto &word : forward)
       	dict.erase(word);
       for (auto &word : backward)
       	dict.erase(word);
       unordered_set<string> nextLevel;
       bool done = false; // guarantee shortest ladder
       for (auto &it : forward){ //traverse each word in the forward -> the current level of the tree;
             string word = it;
             for (auto &c : word){
                   char c0 = c; //store the original;
                   for (c = 'a'; c <= 'z'; ++c) //try each case;
                   if (c != c0){ //avoid futile checking;
                         //using count is an accelerating method;
                         if (backward.count(word)){    // count is O(1) while isChangedByOne is O(size(word)* size(backward))
                               done = true;
                               //keep the tree generation direction consistent;
                               !reversed ? tree[it].push_back(word) : tree[word].push_back(it); 
                         }
                         else if (!done && dict.count(word)){
                               nextLevel.insert(word);
                               !reversed ? tree[it].push_back(word) : tree[word].push_back(it);
                         }
                   }
                   c = c0; //restore the word;
       	}
       }
       return done || buildTree(nextLevel, backward, dict, tree, reversed);
 }
예제 #2
0
 bool wordBreak(string s, unordered_set<string> &dict) {
     if (s.size() == 0){
         return true;
     }
     if (dict.size() == 0){
       return false;
     }
     bool* f = (bool*)malloc(sizeof(bool)*s.size());
     for(int i = 0; i < s.size(); i++){
       f[i] = false;
     }
     for(int i = 0; i < s.size(); i++){
       f[i] = dict.count(s.substr(0,i+1));
       if (f[i]){
         continue;
       }
       for (int j = 0; j < i; ++j){
         if (f[j] && dict.count(s.substr(j+1,i-j))){
           f[i] = true;
           break;
         }
       }
     }
     return f[s.size() - 1];
 }
예제 #3
0
 bool helper(unordered_set<string>& word1, unordered_set<string>& word2, unordered_set<string>& dict){
     if(word1.empty()) return 0;
     if(word1.size() > word2.size()) return helper(word2, word1, dict);
     for(auto v : word1) dict.erase(v);
     for(auto v : word2) dict.erase(v);
     
     ++res;
     bool reach = false;
     unordered_set<string> word3;
     for(auto it = word1.begin(); it != word1.end(); ++it){
         string word = *it;
         for(int i = 0; i < word.size(); ++i){
             char letter = word[i];
             for(int k = 0; k < 26; ++k){
                 word[i] = 'a'+k;
                 if(word2.count(word)){
                     reach = true;
                     return reach;
                 }
                 if(dict.count(word) && !reach){
                     word3.insert(word);
                 }
             }
             word[i] = letter;
         }
     }
     return reach || helper(word2, word3, dict);
 }
예제 #4
0
 vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
     int n = s.length();
     // 要先判断是否能分割,能的话再进行记录,否则TLE
     if(!wordBreak1(s,wordDict)) 
         return vector<string>();
     vector<int> f(n,0);
     vector<vector<string>> ans(n,vector<string>());
     if(wordDict.count(s.substr(0,1))){
         f[0] = 1;
         ans[0].push_back(s.substr(0,1));
     }
     string tmp;
     for(int i = 1;i < n;++i){
         for(int j = 0;j < i;++j){
             tmp = s.substr(j+1,i-j);
             if(f[j] && wordDict.count(tmp)){
                 f[i] = 1;
                 for(int k = 0;k < ans[j].size();++k)
                     ans[i].push_back(ans[j][k]+" "+tmp);
             }
         }
         tmp = s.substr(0,i+1);
         if(wordDict.count(tmp)){
             ans[i].push_back(tmp);
             f[i] = 1;
         }
     }
     return ans[n-1];
 }
예제 #5
0
    vector<string> doit(string s,unordered_set<string> &dict) {
	if(ht.count(s))
	    return ht[s];

	vector<string> ret;
	// if s is contained in dict, it is added into results; but it may be decomposed further
	if(dict.count(s))
	    ret.push_back(s);
	
	int n = s.size();
	for(int i=1;i<n;++i) {
	    string prefix = s.substr(0,i);
	    if(dict.count(prefix)==1) {
		vector<string> ret2 = doit(s.substr(i),dict);
		if(!ret2.empty()) {
		    for(string str : ret2) {
			string tmp = prefix + " " + str;
			ret.push_back(tmp);
		    }		        
//		    break;
		}
	    }
	}
	ht[s] = ret;	
	return ret;
    }
예제 #6
0
 //If there is no '&' before set, the time cost will be tripled;
 int ladderLength(unordered_set<string>& bList, unordered_set<string>& eList, unordered_set<string>& wordList, int len)
 {
     if(bList.empty())
         return 0;
     if(bList.size() > eList.size())
         return ladderLength(eList, bList, wordList, len);
     unordered_set<string> tmpList;
     for(auto it=bList.begin(); it!=bList.end(); it++)
     {
         string cur = *it;
         for(int i=0; i<cur.size(); i++)
         {
             char c0 = cur[i];
             for(char c='a'; c<='z'; c++)
             {
                 cur[i]=c;
                 if(eList.count(cur)) return len+1;
                 if(wordList.count(cur))
                 {
                     tmpList.insert(cur);
                     wordList.erase(cur);
                 }
             }
             cur[i] = c0;
         }
     }
     return ladderLength(tmpList, eList, wordList, len+1);
 }
예제 #7
0
	bool canCross(unordered_set<int>& units, map<pos, bool>& flags, int end, int start, int k) {
		if (start == end) {
			return true;
		}
		if (k - 1 > 0 && start + k - 1 <= end && units.count(start + k - 1)) {
			auto it = flags.find({ start + k - 1, k - 1 });
			if (it == flags.end()) {
				bool can = canCross(units, flags, end, start + k - 1, k - 1);
				if (can) {
					return true;
				}
			}
		}
		if (start + k <= end && units.count(start + k)) {
			auto it = flags.find({ start + k, k });
			if (it == flags.end()) {
				bool can = canCross(units, flags, end, start + k, k);
				if (can) {
					return true;
				}
			}
		}
		if (start + k + 1 <= end && units.count(start + k + 1)) {
			auto it = flags.find({ start + k + 1, k + 1 });
			if (it == flags.end()) {
				bool can = canCross(units, flags, end, start + k + 1, k + 1);
				if (can) {
					return true;
				}
			}
		}
		flags[{start, k}] = false;
		return false;
	}
예제 #8
0
 vector<string> findWords(vector<string>& words) {
     vector<string> res;
     int last = -1;
     for (auto &word : words) {
         bool valid = true;
         for (auto c : word) {
             c = tolower(c);
             if (row1.count(c)) {
                 if (last != -1 && last != 1) {
                     valid = false;
                     break;
                 }
                 last = 1;
             } else if (row2.count(c)) {
                 if (last != -1 && last != 2) {
                     valid = false;
                     break;
                 }
                 last = 2;
             } else {
                 if (last != -1 && last != 3) {
                     valid = false;
                     break;
                 }
                 last = 3;
             }
         }
         if (valid) res.push_back(word);
     }
     return res;
 }
예제 #9
0
    bool wordBreak(string s){
        if (cache.find(s) != cache.end()) return cache[s];

        if (Dict->count(s)) return cache[s] = true;
        for (int i = 1; i < s.length(); i++){
            string left = s.substr(0, i);
            if (Dict->count(left) && wordBreak(s.substr(i, s.length() - i))) return cache[s] = true;
        }

        return cache[s] = false;
    }
예제 #10
0
void SESELoop::buildLoopMemberSet(BasicBlock& backEdgeDestination, const unordered_multimap<BasicBlock*, BasicBlock*>& destToOrigin, unordered_set<BasicBlock*>& members, unordered_set<BasicBlock*>& entries, unordered_set<BasicBlock*>& exits)
{
	// Build paths to back-edge start nodes.
	unordered_set<BasicBlock*> sinkNodeSet;
	auto range = destToOrigin.equal_range(&backEdgeDestination);
	for (auto iter = range.first; iter != range.second; iter++)
	{
		sinkNodeSet.insert(iter->second);
	}
	
	auto pathsToBackNodes = findPathsToSinkNodes(&backEdgeDestination, sinkNodeSet);
	
	// Build initial loop membership set
	for (const auto& path : pathsToBackNodes)
	{
		members.insert(path.begin(), path.end());
	}
	
	// The path-to-sink-nodes algorithm won't follow back edges. Because of that, if the cycle contains a
	// sub-cycle, we need to add its member nodes. This is probably handled by the loop membership refinement
	// step from the "No More Gotos" paper, but as noted below, we don't use that step.
	unordered_set<BasicBlock*> newMembers;
	for (BasicBlock* bb : members)
	{
		auto range = loopMembers.equal_range(bb);
		for (auto iter = range.first; iter != range.second; iter++)
		{
			newMembers.insert(iter->second);
		}
	}
	members.insert(newMembers.begin(), newMembers.end());
	
	for (BasicBlock* member : members)
	{
		loopMembers.insert({&backEdgeDestination, member});
		
		for (BasicBlock* pred : predecessors(member))
		{
			if (members.count(pred) == 0)
			{
				entries.insert(member);
			}
		}
		
		for (BasicBlock* succ : successors(member))
		{
			if (members.count(succ) == 0)
			{
				exits.insert(succ);
			}
		}
	}
}
예제 #11
0
    bool wordBreak(string s, unordered_set<string> &dict) {
        int stringLength = s.size();
        if (stringLength == 0 || dict.count(s) > 0) return true;
        int i;
        for (i = 1; i < stringLength; i++) {
            string word = s.substr(0, i);
            string remain = s.substr(i, stringLength-i);
	    std::cout << "word: " << word << " remain: " << remain << std::endl;
            if (dict.count(word) > 0) if (wordBreak(remain, dict)) return true;	// cannot return wordBreak(remain, dict) directly.
            if (dict.count(remain) > 0) if (return wordBreak(word, dict)) return true;
        }
        return false;
    }
예제 #12
0
 vector<string> wordBreak(string s, unordered_set<string> &dict) {
     int n = (int)s.length();
     for (int i=0; i<n; ++i) dp[i].clear();
     for (int i=0; i<n; ++i) {
         if (dict.count(s.substr(0, i+1))) dp[i].push_back(-1);
         for (int j=i; j>0; --j) if (dict.count(s.substr(j, i-j+1)) && !dp[j-1].empty()) {
             dp[i].push_back(j-1);
         }
     }
     vector <string> ret, cc;
     dfs(n-1, s, cc, ret);
     return ret;
 }
예제 #13
0
 bool dfs(char node, unordered_set<char> &visited, stack<char> &stk, unordered_map<char, unordered_set<char>> &links, unordered_set<char> path)
 {
     visited.insert(node);
     path.insert(node);
     for(auto nb:links[node])
     {
         if(path.count(nb)==1) return false;
         if(visited.count(nb)==0)
             if(!dfs(nb, visited, stk, links, path)) return false;
     }
     stk.push(node);
     return true;
 }
예제 #14
0
 bool wordBreak1(string s, unordered_set<string>& wordDict) {
     int n = s.length();
     // f[i]表示以s[i]为结尾的子串是否能够拆分
     vector<int> f(n+1,0);
     f[0] = wordDict.count(s.substr(0,1));
     for(int i = 1;i < n;++i){
         for(int j = 0;j < i;++j){
             if(f[j] && wordDict.count(s.substr(j+1,i-j)))
                 f[i] = 1;
         }
         if(wordDict.count(s.substr(0,i+1))) f[i] = 1;
     }
     return f[n-1];
 }
예제 #15
0
 void getNext(string s, unordered_set<string> &dict, unordered_set<string> &isVisited, unordered_set<string> &nextStrs) {
     for(int i = 0; i < s.length(); ++i) {
         string nextStr(s);
         for(char c = 'a'; c <= 'z'; ++c) {
             if(c != nextStr[i]) {
                 swap(c, nextStr[i]);
                 if(dict.count(nextStr) && !isVisited.count(nextStr)) {
                     nextStrs.insert(nextStr);
                     isVisited.insert(nextStr);
                 }
                 swap(c, nextStr[i]);
             } 
         }
     }
 }
예제 #16
0
 void dfs(vector<vector<char> >& board, int i, int j, string candidate, vector<vector<bool> >& visited, vector<string>& ans) {
     if(prefix.count(candidate) == 0)
         return;
     if(dict.count(candidate))
         ans.push_back(candidate);
     for(int dir = 0; dir < 4; dir++) {
         int ii = i + dx[dir];
         int jj = j + dy[dir];
         if(ii < 0 || jj < 0 || ii >= m || jj >= n || visited[ii][jj])
             continue;
         visited[ii][jj] = true;
         dfs(board, ii, jj, candidate + board[ii][jj], visited, ans);
         visited[ii][jj] = false;
     }
 }
예제 #17
0
    void bfs(string &start, string &end, unordered_set<string> &dict,
             vector<vector<string>> &ret)
    {
        size_t len = start.size();
        if (len != end.size() || len == 0 || start == end) return; // invalid

        unordered_set<string> used; // avoid duplicate word in the path
        unordered_set<string> levelUsed; // delete the same level duplicate words using set
        unordered_multimap<string, string> father; // use it to get path

        queue<string> q;
        q.push(start);
        int levelSize = 1;
        bool found = false;

        while (!q.empty()) {
            string cur = q.front();
            string t(cur);
            q.pop();
            levelSize--;

            for (size_t i = 0; i < len; i++) {
                for (char c = 'a'; c <= 'z'; c++) {
                    if (t[i] == c) continue; // itself

                    t[i] = c;
                    if (t == end) { // find it
                        found = true;
                        father.insert(make_pair(t, cur));
                        break;
                    }

                    // t is not used and is in the dict
                    if (used.count(t) == 0 && dict.count(t) != 0) {
                        // don't push it to queue, it will push many duplicate elements
                        // just push levelUsed element
                        // q.push(t); // don't push it to queue, it will push many nonused elements
                        levelUsed.insert(t);
                        father.insert(make_pair(t, cur));
                    }
                }
                t[i] = cur[i]; // reset t to cur
            }

            if (levelSize == 0) { // finish one level
                if (found) break;
                for (auto e : levelUsed) {
                    used.insert(e);
                    q.push(e); // insert here
                }
                levelSize = q.size();
                levelUsed.clear();
            }
        }

        if (found) {
            vector<string> path;
            getPath(end, start, dict, father, ret, path);
        }
    }
예제 #18
0
 int ladderLength(string start, string end, unordered_set<string> &dict) {
     // Start typing your C/C++ solution below
     // DO NOT write int main() function
     queue<string> q;
     map<string, int> l;
     
     q.push(start);
     l[start] = 1;
     
     while(!q.empty())
     {
         string w = q.front();
         q.pop();
         if(adj(w,end)) return l[w]+1;
         for(int i=0;i<w.length();i++)
         {
             for(int j='a';j<='z';j++)
             {
                 string t = w;                    
                 if(w[i] == 'j') continue;
                 t[i] = j;
                 if(!dict.count(t)) continue;                                
                 if(l[t]) continue;
                 if(adj(w,t))
                 {
                     q.push(t);
                     l[t] = l[w]+1;
                 }
             }
         }
     }
     return 0;
 }
예제 #19
0
void findWordBreak(string &s, unordered_set<string> &dict, int start, vector<string> &sol, vector<string> &sentences, vector<int>&possible) 
{
    if(start==s.size() && !sol.empty()) 
    {   
        // find word break
        string temp = sol[0];
        for(int i=1; i<sol.size(); i++) 
        {
            temp.append(" "+sol[i]);
        }
        sentences.push_back(temp);
    }
        
    string word;
    for(int i=start; i<s.size(); i++) 
    {
        word.push_back(s[i]);
        if(dict.count(word)!=0 && possible[i+1] == 1) 
        {
            sol.push_back(word);
            int size_record = sentences.size();
            findWordBreak(s, dict, i+1, sol, sentences, possible);
            if (sentences.size() == size_record )
            {
                possible[i+1] = 0;
            }
            sol.pop_back();
        }
    }
}
예제 #20
0
 int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
     if (beginWord == endWord) return 1;
     int dist = 2;
     unordered_set<string> head, tail, *phead, *ptail;
     head.insert(beginWord);
     tail.insert(endWord);
     while (!head.empty() && !tail.empty()) {
         if (head.size() < tail.size()) {
             phead = &head;
             ptail = &tail;
         } else {
             phead = &tail;
             ptail = &head;
         }
         unordered_set<string> temp;
         for (auto word : *phead) {
             for (int i = 0; i < word.length(); ++i) {
                 char c = word[i];
                 for (int j = 0; j < 26; ++j) {
                     word[i] = 'a' + j;
                     if (ptail->count(word)) return dist;
                     if (wordList.count(word)) {
                         wordList.erase(word);
                         temp.insert(word);
                     }
                 }
                 word[i] = c;
             }
         }
         dist++;
         swap(*phead, temp);
     }
     return 0;
 }
 int trapRainWater(vector<vector<int>>& heightMap) {
     if (heightMap.size() < 3 || heightMap[0].size() < 3)
     {
         return 0;
     }
     
     int row = (int)(heightMap.size());
     int col = (int)(heightMap[0].size());
     initialize(heightMap, row, col);
     
     int result = 0;
     while (pq.size() > 0)
     {
         Triple top = pq.top();
         pq.pop();
         
         // loop 4 directions
         for (auto dir: directions)
         {
             int new_x = top.x + dir[0];
             int new_y = top.y + dir[1];
             int point = convertPoint(new_x, new_y, col);
             if (inBoundary(new_x, new_y, heightMap) && visited.count(point) == 0)
             {
                 int new_height = heightMap[new_x][new_y];
                 result += max(0, top.height - new_height);
                 add(max(top.height, new_height), new_x, new_y, col);
             }
         }
     }
     
     return result;
 }
예제 #22
0
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
        if(beginWord==endWord)  return 1;
        unordered_map<string, int> dist;
        dist[beginWord] = 1;
        queue<string> wordQue;
        wordQue.push(beginWord);

        while(!wordQue.empty()){
            string current = wordQue.front();   wordQue.pop();
            for(int i=0;i<current.size();i++){
                for(char c='a';c<='z';c++){
                    if(current[i]==c)   continue;
                    string newWord = current;
                    newWord[i] = c;
                    if(newWord == endWord)  return dist[current] + 1;

                    if(wordDict.count(newWord) && !dist.count(newWord)){
                        dist[newWord] = dist[current] + 1;
                        wordQue.push(newWord);
                    }
                }
            }
        }

        return 0;
    }
    bool wordPatternMatchHelper(const string& pattern, int patternIndex,
                                const string& word, int wordIndex,
                                unordered_map<char, string>& char2StringMap,
                                unordered_set<string>& mappedStringSet) {
        if (patternIndex == (int)pattern.size() && wordIndex == (int)word.size()) return true;
        if (patternIndex == (int)pattern.size() || wordIndex == (int)word.size()) return false;

        for (int i = wordIndex; i < (int)word.size(); ++i) {
            string subWord = word.substr(wordIndex, i-wordIndex+1);
            char p = pattern[patternIndex];
            auto it = char2StringMap.find(p);
            if (it != char2StringMap.end() && it->second == subWord) {
                if (wordPatternMatchHelper(pattern, patternIndex+1, word, i+1, char2StringMap, mappedStringSet)) {
                    return true;
                }
            } else if (it == char2StringMap.end()) {
                if (mappedStringSet.count(subWord)) continue;
                char2StringMap[p] = subWord;
                mappedStringSet.insert(subWord);
                if (wordPatternMatchHelper(pattern, patternIndex+1, word, i+1, char2StringMap, mappedStringSet)) {
                    return true;
                }
                char2StringMap.erase(p);
                mappedStringSet.erase(subWord);
            }
        }

        return false;
    }
    int ladderLength(string start, string end, unordered_set<string> &dict) {
        
        // Using a map for two purposes: 
        //   1) store the distince so far.
        //   2) remove the duplication 
        map<string, int> dis;
        dis[start] = 1;
        
        queue<string> q;
        q.push(start);
        
        while(!q.empty()){

            string word = q.front(); 
            q.pop();
            
            if (word == end) {
                break;
            }
            
            for (int i=0; i<word.size(); i++){
                string temp = word;
                for(char c='a'; c<='z'; c++){
                    temp[i] = c;
                    if (dict.count(temp)>0 && dis.count(temp)==0){
                        dis[temp] = dis[word] + 1;
                        q.push(temp);
                    }
                }
            }
        }
        return (dis.count(end)==0) ? 0 : dis[end];
        
    }
예제 #25
0
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        if (beginWord.size() != endWord.size()) return 0;
        if (beginWord.empty() || endWord.empty()) return 1;
        if (wordList.size() == 0) return 0;

        int distance = 1;
        queue<string> queToPush, queToPop;
        queToPop.push(beginWord);
        while (wordList.size() > 0 && !queToPop.empty()) {
            while (!queToPop.empty()) {
                string str(queToPop.front());
                queToPop.pop();
                for (int i = 0; i < str.size(); i++) {
                    for (char j = 'a'; j <= 'z'; j++) {
                        if (j == str[i]) {
                            continue;
                        }
                        char temp = str[i];
                        str[i] = j;
                        if (str == endWord) return distance + 1;
                        if (wordList.count(str) > 0) {
                            queToPush.push(str);
                            wordList.erase(str);
                        }
                        str[i] = temp;
                    }
                }
            }
            swap(queToPush, queToPop);
            distance++;
        }
        return 0;
    }
예제 #26
0
    vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
        const int n = s.length();

        size_t max_len = 0;
        for (const auto& str: wordDict) {
            max_len = max(max_len, str.length());
        }

        vector<bool> canBreak(n + 1, false);
        vector<vector<bool>> valid(n, vector<bool>(n, false));
        canBreak[0] = true;
        for (int i = 1; i <= n; ++i) {
            for (int l = 1; l <= max_len && i - l >= 0; ++l) {
                if (canBreak[i - l] && wordDict.count(s.substr(i - l, l))) {
                    valid[i - l][i - 1] = true;
                    canBreak[i] = true;
                }
            }
        }

        vector<string> result, path;
        if (canBreak[n]) {
            wordBreakHelper(s, valid, 0, &path, &result);
        }
        return result;
    }
예제 #27
0
bool dfs(int mask, int left, pfunc P, int depth){
  // for (int i = 0 ; i < depth; i++) printf("%d\t",path[i]); printf("\n");
   if (mask==0) return true;
   if (needprejudge) if (bitcount(mask)<=prejudgesize)   if (!prejudge(mask,left)) return false;
   visitedmaskset.insert(mask);
   if (totcnt > MAXX) return false;
   if (left ==0) return false;
   int buf[32]; int n_buf;
   memset(buf,0,sizeof(buf));
   P(buf,n_buf,mask);
   for (int i = 0 ; i < n_buf; i++) {
      int todel;
      todel=path[depth]=buf[i];
      int backdegree= degree[todel]; degree[todel] = 0;
      for (int j = 0 , jm=1; j<map_n; j++, jm<<=1)
        if ((jm & mask) && graph[todel][j]) degree[j]--;
      int newmask = 0 ;
      for (int j = 0 , jm=1; j<map_n; j++, jm<<=1)
        if (degree[j]) newmask += jm;
      if (visitedmaskset.count(newmask)==0)  {
         if (dfs(newmask,left-1,P,depth+1)) return true;
         totcnt++;
      }
      degree[todel] = backdegree;
      for (int j = 0 , jm=1; j<map_n; j++, jm<<=1)
        if ((jm & mask) && graph[todel][j]) degree[j]++;
   }
}
예제 #28
0
	int ladderLength(string start, string end, unordered_set<string> &dict)
	{
		if (start == end)
			return 1;
		dict.insert(end);
		int n = start.size();
		queue<pair<string, int>> que;
		que.push(make_pair(start, 1));
		dict.erase(start);
		while (!que.empty())
		{
			auto top = que.front();
			que.pop();

			for (int i = 0; i < n; ++i)
			{
				for (char c = 'a'; c <= 'z'; ++c)
				{
					string temp = top.first;
					temp[i] = c;
					if (dict.count(temp))
					{
						if (temp == end)
							return top.second+1;
						que.push(make_pair(temp, top.second+1));
						dict.erase(temp);
					}
				}
			}
		}
		return 0;
	}
예제 #29
0
 int bfs(string beginWord, string endWord, unordered_set<string> wordList)
 {
 	queue<pair<string,int> > q;
 	q.push(make_pair(beginWord,1));
 	unordered_set<string> visited;
 	visited.insert(beginWord);
 	bool found = false;
 	while(!q.empty())
 	{
 		pair<string,int> cur = q.front();
 		q.pop();
 		string word = cur.first;
 		int len = word.size();
 		for (int i = 0; i < len; ++i)
 		{
 			string newWord(word);
 			for(int j = 0; j < 26;++j)
 			{
 				newWord[i] = 'a' + j;
 				if(newWord == endWord)
 				{
 					found = true;
 					return cur.second+1;
 				}
 				if(wordList.count(newWord) > 0 && visited.count(newWord) == 0)
 				{
 					visited.insert(newWord);
 					q.push(make_pair(newWord,cur.second+1));
 				}
 			}
 		}
 	}
 	if(found == false)
 		return 0;
 }
예제 #30
0
 void dfs(string pattern, string str, unordered_map<char, string> decode, unordered_map<char, int> count, unordered_set<string> used, int str_len, int already_len){
     if(pattern.empty()) 
         if(str.empty()){
             found = true;
             return;
         } else
             return;
     cout << pattern << ' ' << str << endl;
     char cur = pattern[0];
     if(decode.count(cur)){
         if(str.find(decode[cur]) == 0)
             dfs(pattern.substr(1), str.substr(decode[cur].length()), decode, count, used, str_len, already_len);
         else
             return;
     } else {
         for(int len = 1; already_len + len * count[cur] <= str_len && found != true; len++){
             if(!used.count(str.substr(0, len))){
                 decode[cur] = str.substr(0, len);
                 used.insert(str.substr(0, len));
                 dfs(pattern.substr(1), str.substr(len), decode, count, used, str_len, already_len + len * count[cur]);
                 used.erase(str.substr(0, len));
             }
         }
     }    
 }