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
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {

        queue<pair<string, int> > que;
        if (wordDict.find(beginWord) == wordDict.end()){
            return -1;
        }        

        que.push(make_pair(beginWord, 1));
        wordDict.erase(beginWord);

        while (!que.empty()){

            auto front = que.front();
            que.pop();

            if (front.first == endWord) return front.second;

            for (int i = 0; i < front.first.length(); i++){
                string tmp = front.first;
                for (char j = 'a'; j <= 'z'; j++){
                    tmp[i] = j;
                    if (wordDict.find(tmp) != wordDict.end()){
                        que.push(make_pair(tmp, front.second + 1));
                        wordDict.erase(tmp);
                    }
                }
            }

        }

        return 0;

    }
예제 #3
0
//这题很有意思,不知道从哪里下手
//BFS
//不能这么循环,因为会删光了
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList)
{
    if(beginWord.size() != endWord.size()) return 0;
    if(beginWord.empty() || endWord.empty()) return 0;

    queue<string> path;
    path.push(beginWord);
    int level = 1;
    wordList.erase(beginWord);
    while(wordList.size() >= 0 && !path.empty()){
        int len = path.size();
        for(int count = 0; count<len; count++){
            string curWord = path.front();
            path.pop();
            for(int i = 0; i<curWord.size(); i++){
                string tmp = curWord;
                for(char j = 'a'; j<='z'; j++){
                    if(tmp[i] == j) continue;
                    tmp[i] = j;
                    if(tmp == endWord) return level+1;
                    if(wordList.find(tmp) != wordList.end()) path.push(tmp);
                    wordList.erase(tmp);
                }
            }
        }
        level++;
    }
    return 0;
}
예제 #4
0
 int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
     unordered_map<string, int> hash;
     if (wordDict.find(beginWord) != wordDict.end()) wordDict.erase(beginWord);
     if (wordDict.find(endWord) == wordDict.end()) wordDict.insert(endWord);
     queue<string> q;
     q.push(beginWord);
     hash[beginWord] = 1;
     while (!q.empty()) {
         string cur = q.front();
         q.pop();
         if (cur == endWord) return hash[cur];
         int dis = hash[cur];
         for (int i = 0; i < cur.size(); i ++) {
             for (int j = 0; j < 26; j ++) {
                 char ch = 'a' + j;
                 string temp = cur;
                 temp[i] = ch;
                 if (temp != cur && wordDict.find(temp) != wordDict.end() && hash.find(temp) == hash.end()) {
                     hash[temp] = dis + 1;
                     wordDict.erase(temp);
                     q.push(temp);
                 }
             }
         }
     }
     return 0;
 }
예제 #5
0
	int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList)
	{
		if (beginWord == endWord) return 2;
		int depth = 1;
		unordered_set<string> forward, backward;
		forward.insert(beginWord);
		backward.insert(endWord);
		while (!forward.empty())
		{
			unordered_set<string> nextLevel;
			for (auto& w : forward) wordList.erase(w);
			for (auto& w : backward) wordList.erase(w);
			for (auto& word : forward)
			{
				string cur(word);
				for (auto& c : cur)
				{
					char c0 = c;
					for (c = 'a'; c <= 'z'; ++c)
					{
						if (c != c0)
						{
							if (backward.count(cur)) return depth + 1;
							if (wordList.count(cur)) nextLevel.insert(cur);
						}
					}
					c = c0;
				}
			}
			depth++;
			forward.swap(nextLevel);
			if (forward.size() > backward.size()) backward.swap(forward);
		}
		return 0;
	}
예제 #6
0
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        int len = beginWord.length(), level = 1, nodesATLevel;  // return the length of the ladder, not # transformation
        string str;
        char orig;
        deque<string> qStart, qEnd, *q1, *q2;
        unordered_set<string> startFrontier, endFrontier, *f1, *f2;

        qStart.push_back(beginWord);
        qEnd.push_back(endWord);
        startFrontier.insert(beginWord);
        endFrontier.insert(endWord);
        wordList.erase(beginWord);  // mark every visited node by removing it from the dict
        wordList.erase(endWord);
        while (!qStart.empty() && !qEnd.empty())
        {
            ++level;
            if (qStart.size() < qEnd.size())
            {
                q1 = &qStart;  // iterate through q1, to match strings in q2
                q2 = &qEnd;
                f1 = &startFrontier;
                f2 = &endFrontier;
            }
            else
            {
                q1 = &qEnd;
                q2 = &qStart;
                f1 = &endFrontier;
                f2 = &startFrontier;
            }
            f1->clear();  // pointer notation
            nodesATLevel = q1->size();
            for (int i = 0; i < nodesATLevel; ++i)
            {
                str = q1->front();
                q1->pop_front();
                for (int j = 0; j < len; ++j)
                {
                    orig = str[j];
                    for (char c = 'a'; c <= 'z'; ++c)
                    {
                        //if (c == orig)  // if start == end, length should be 1 or 2??
                        //    continue;
                        str[j] = c;
                        if (f2->find(str) != f2->end())
                            return level;
                        if (wordList.find(str) != wordList.end())
                        {
                            q1->push_back(str);
                            f1->insert(str);
                            wordList.erase(str);  // mark as visited
                        }
                    }
                    str[j] = orig;
                }
            }
        }
        return 0;
    }
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dic) {
      dic.erase(start); dic.erase(end);
      vector<string> dict(dic.begin(), dic.end());
      dict.push_back(end);
      dict.insert(dict.begin(), start);
      unordered_map<string, vector<int> > map;

      int starti = 0, endi = dict.size() - 1;

      for (int i = 1; i < dict.size(); i++) {  /* record the variations of every word in dict */
          string tmp = dict[i];
          for (int j = 0; j < tmp.length(); j++) {
            tmp[j] = '\0';
            if (map.find(tmp) == map.end())
              map[tmp] = vector<int>();
            map[tmp].push_back(i);
            tmp[j] = dict[i][j];
          }
      }

      queue<TransNode*> trans;
      vector<vector<string> > res;
      vector<int> set(dict.size(), -1);
      trans.push(new TransNode(starti));
      set[starti] = 0;

      while (!trans.empty()) {
        TransNode *tran = trans.front(); trans.pop();
        int tmpi = tran->str;
        string tmp = dict[tmpi];

        if (!res.empty() && tran->lvl >= res[0].size()) /* the current level is greater than the shortest path's length */
          break;

        if (tmp == end) {   /* meet another shortest path, add to result */
          res.push_back(vector<string>(tran->lvl+1));
          for (TransNode *t = tran; t; t = t->parent)
            res.back()[t->lvl] = dict[t->str];
          continue;
        }

        for (int i = 0; i < tmp.length(); i++) {
          tmp[i] = '\0';
          for (auto s = map[tmp].begin(); s != map[tmp].end(); s++) {
            if (dict[*s] == dict[tmpi])
              continue;
              
            if (set[*s] == -1 ||  set[*s] == tran->lvl+1) {
              trans.push(new TransNode(*s, tran));
              set[*s] = tran->lvl+1;
            }
          }

          tmp[i] = dict[tmpi][i];
        }
      }

      return res;
    }
예제 #8
0
 int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
     unordered_set<string> words1, words2;
     words1.insert(beginWord);
     words2.insert(endWord);
     wordList.erase(beginWord);
     wordList.erase(endWord);
     return ladderLengthHelper(words1, words2, wordList, 1);
 }
예제 #9
0
 int ladderLength(string start, string end, unordered_set<string> &dict) {
     // IMPORTANT: Please reset any member data you declared, as
     // the same Solution instance will be reused for each test case.
     
     queue<string> queueToPop;
     queue<string> queueToPush;
     int           distance  = 1;
     
     dict.erase (start);
     dict.erase (end);
     
     queueToPush.push (start);
     
     while (queueToPush.size () > 0)
     {
         swap (queueToPop, queueToPush);
         vector<string> toBeDelete;
         
         while (queueToPop.size () > 0)
         {
             string current = queueToPop.front ();
             
             queueToPop.pop ();
             
             for (int i = 0; i < current.size (); i++)
             {
                 for (char c = 'a'; c <= 'z'; c++)
                 {
                     if (current[i] != c)
                     {
                         string temp = current;
                     
                         temp[i] = c;
                         
                         if (temp.compare (end) == 0)
                         {
                             return (distance + 1);
                         }
                         else if (dict.count (temp) > 0)
                         {
                             queueToPush.push (temp);
                             dict.erase (temp);
                         }
                     }
                 }
             }
         }
         
         for (auto s : toBeDelete)
         {
             dict.erase (s);
         }
         
         distance++;
     }
     
     return 0;
 }
예제 #10
0
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) 
    {
		if(wordDict.empty())
			return 0;
		stepWord *tempStep = new stepWord();
		tempStep->word = beginWord;
		tempStep->step = 1;
        queue<stepWord*> sBegin;		
		sBegin.push(tempStep);
		stepWord *tempStepend = new stepWord();
		tempStepend->word = endWord;
		tempStepend->step = 1;
		queue<stepWord*> sEnd;
		sEnd.push(tempStepend);
		stepWord *ptrBegin;
		stepWord *ptrEnd;
		while(!sBegin.empty() || !sEnd.empty())
		{
			if(!sBegin.empty())
			{
				ptrBegin = sBegin.front();
				sBegin.pop();
			}
			if(!sEnd.empty())
			{
				ptrEnd = sEnd.front();
				sEnd.pop();
			}
			cout << "Õ»¶¥µ¥´Ê£º" << ptrBegin->word << "\t" << ptrEnd->word <<endl;
			if(isSimilar(ptrBegin->word, ptrEnd->word))
				return ptrBegin->step + ptrEnd->step;						
			if(wordDict.empty())
				continue;
			for(unordered_set<string>::iterator p = wordDict.begin(); p != wordDict.end();)
			{
				if(isSimilar(*p, ptrBegin->word))
				{
					stepWord *tempStep = new stepWord();
					tempStep->word = *p;
					tempStep->step = ptrBegin->step + 1;
					sBegin.push(tempStep);
					p = wordDict.erase(p);
				}
				else if(isSimilar(*p, ptrEnd->word))
				{
					stepWord *tempStep = new stepWord();
					tempStep->word = *p;
					tempStep->step = ptrEnd->step + 1;
					sEnd.push(tempStep);
					p = wordDict.erase(p);
				}
				else
					++ p;
			}
		}
		return 0;
    }
int ladderLength(string beginWord, string endWord, unordered_set<string>& dict) {
	if (beginWord == endWord) return 1;
	unordered_set<string> words1, words2;
	words1.insert(beginWord);
	dict.erase(beginWord);
	words2.insert(endWord);
	dict.erase(endWord);
	return searchwithDoubleBFS(words1, words2, dict, 1);
}
    // looking for connection from both ends
    bool bfs(unordered_set<string> &forward, unordered_set<string> &backward, bool isForward, 
                unordered_set<string> &wordList, unordered_map<string, vector<string>> &transMap) {
        if (forward.empty() || backward.empty())
        {
            return false;
        }

        // always do bfs with less nodes
        if (forward.size() > backward.size())
        {
            return bfs(backward, forward, !isForward, wordList, transMap);
        }

        // remove added node in the wordList to avoid duplication
        unordered_set<string>::iterator it;
        for (it = forward.begin(); it != forward.end(); it++)
        {
            wordList.erase(*it);
        }

        for (it = backward.begin(); it != backward.end(); it++)
        {
            wordList.erase(*it);
        }

        unordered_set<string> nextlevel;
        bool isConnected = false;
        for (it = forward.begin(); it != forward.end(); it++)
        {
            string word = *it;
            for (int i = 0; i < word.size(); i++)
            {
                for (char ch = 'a'; ch <= 'z'; ch++)
                {
                    if (word[i] != ch)
                    {
                        // word is in forward list, str is in backward list
                        string str(word);
                        str[i] = ch;
                        if (backward.find(str) != backward.end())
                        {
                            isConnected = true;
                            connect(word, str, isForward, transMap);
                        }
                        else if (!isConnected && wordList.find(str) != wordList.end())
                        {
                            nextlevel.insert(str);
                            connect(word, str, isForward, transMap);
                        }
                    }
                }
            }
        }

        return isConnected || bfs(nextlevel, backward, isForward, wordList, transMap);
    }
예제 #13
0
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict){
        dict.emplace(start);
        dict.emplace(end);
        unordered_map<string, vector<string>> from;
        queue<string> que;
        que.push(start);
        dict.erase(start);

        int endLevel = -1;
        int level = 0;

        while(!que.empty()){
            if(endLevel != -1) break;
            int size = que.size();
            unordered_set<string> toPush;//this is acctually what the next level is
            for(int ttt = 0; ttt < size; ttt++){
                string front = que.front();
                if(front == end){
                    endLevel = level;
                    break;
                }

                for(unsigned int i = 0; i < front.size(); i++){
                    string neighbor = front;
                    for(int j = 0; j < 26; j++){
                        neighbor[i] = (char)((int)'a' + j);
                        if(neighbor == front) continue;

                        if((dict.count(neighbor) != 0)){
                            from[neighbor].push_back(front);
                            toPush.emplace(neighbor);
                        }
                    }
                }
                que.pop();
            }
            level++;
            for(unordered_set<string>::iterator itr = toPush.begin(); itr != toPush.end(); itr++){
                string temp = *itr;
                que.push(temp);
                dict.erase(temp);
                //every time after next level is determined, erase them from dict
                //since they won't be at the next next level(we need to exclude them from the future check)
            }
        }

        vector<vector<string>> result;
        if(from[end].size() == 0) return result;
        vector<string> tempRes;

        tempRes.push_back(end);
        help(result, tempRes, endLevel, start, end, from);
        return result;
    }
예제 #14
0
   vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        vector<vector<string> > ret;
        unordered_map<string,string> previous;
     
        queue<pair<string,int> > coada;
        coada.push(make_pair(start,0));
		dict.erase(start);
		dict.erase(end);
        if(start==end && dict.empty()==true ) 
            return ret;
        pair<string,int> curent;
		previous[start]="###";
        int n;
		int lungime = 0;
        while(coada.empty()==false){
			curent = coada.front();
			coada.pop();
			if(lungime !=0 ){
				if(curent.second+1 !=lungime) break;
			}
            n = curent.first.length()-1;
            string aux = curent.first;
            char c ;
            for(int i=0;i<=n;++i){
                c = aux[i];
                for(int j='a';j<='z';++j){
                    aux[i]=j;
                    if(curent.first == aux) continue;
                    if(aux==end){
                        vector<string> forret;
                        forret.push_back(end);
						forret.push_back(curent.first);
						string prev = previous[curent.first];
						
						while(prev!="###"){
							forret.push_back(prev);
							prev = previous[prev];
						}
						reverse(forret.begin(),forret.end());
						ret.push_back(forret);
						lungime = curent.second+1;
                    }else
                    if(dict.find(aux)!=dict.end()){
                        coada.push(make_pair(aux,curent.second+1));
						previous[aux]=curent.first;
						dict.erase(aux);
                    }
                }
				 aux[i] = c;
            }
        }
		
        return ret;
    }
예제 #15
0
 int ladderLength(string start, string end, unordered_set<string> &dict) {
     // Start typing your C/C++ solution below
     // DO NOT write int main() function
     if(start.size()!=end.size() || dict.empty())
         return 0;
     //dict.insert(end);
     queue<string> q[2];
     int cur = 0;
     q[cur].push(start);
     int length = 0;
     bool find = false;
     while(!q[cur].empty())
     {
         while(!q[cur].empty())
         {
             string s = q[cur].front();
             q[cur].pop();
             int ssize = s.size();
             for(int i = 0; i < ssize && !find; i++)
             {
                 string tmp = s;
                 for(int j = 'a'; j <= 'z'; j++)
                 {
                     tmp[i] = j;
                     if(tmp == s)
                     {
                         dict.erase(s);
                         continue;
                     }
                     if(tmp == end && length != 0)
                     {
                         find = true;
                         break;
                     }
                     if(dict.find(tmp) != dict.end())
                     {
                         if(tmp == end)
                         {
                             find = true;
                             break;
                         }
                         q[cur^1].push(tmp);
                         dict.erase(tmp);
                     }
                 }
             }
             if(find)
                 return length+2;
         }
         cur ^= 1;
         length++;
     }
     return 0;
 }
예제 #16
0
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict)
{
	unordered_set<string> s1;
	unordered_set<string> s2;
	s1.insert(beginWord);
	s2.insert(endWord);
	wordDict.erase(beginWord);
	wordDict.erase(endWord);

	return ladderLengthHelper(s1,s2,wordDict,2);

}
예제 #17
0
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict)
    {
        unordered_set<string> qStr[2];
        //we should not erase the word when it being inserted to the qStr, because it may turn up twice or more times at the same level. Instead, we should erase the whole level of qStr at the same time.
        k = 0;
        qStr[k % 2].insert(start);
        found = false;

        dict.insert(start);
        dict.insert(end);
        
        dict.erase(dict.find(start));
        
        while(!qStr[k % 2].empty())
        {
            unordered_set<string>::iterator ite = qStr[k % 2].begin();
            string str = *ite;
            qStr[k % 2].erase(ite);

            if(str == end)
            {
                found = true;
                continue;
            }
            if(!found)
            {
                for(int i = 0; i < str.length(); i++)
                {
                    string tmp = str;
                    for(int j = 0; j < 26; j++)
                    {
                        tmp[i] = 'a' + j;
                        if(inDict(tmp, dict))
                        {
                            childToParent[tmp].push_back(str);
                            qStr[(k + 1) % 2].insert(tmp);
                        }
                    }
                }
            }
            if(qStr[k % 2].empty() && !found)
            {
                k++;
                //erase the whole level from dict
                for(unordered_set<string>::iterator ite = qStr[k % 2].begin(); ite != qStr[k % 2].end(); ite++)
                {
                    dict.erase(dict.find(*ite));
                }
            }
        }
        findPath(end, start);
        return result;
    }
 void addword(string word, unordered_set<string>& wordList, queue<string>& beingVisited ){
 	wordList.erase(word);
 	for(int i = 0; i < word.size(); ++i){
 		char letter = word[i];
 		for(int j = 1; j < 26; ++j){
 			word[i] = 'a' + j;
 			if(wordList.find(word) != wordList.end()){
 				beingVisited.push(word);
 				wordList.erase(word);
 			}
 		}
 		word[i] = letter;
 	}
 }
예제 #19
0
 vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
     head = start;
     tail = end;
     dict.erase(start);
     dict.erase(end);
     unordered_set<string> Head_set = { start };
     unordered_set<string> Tail_set = { end };
     unordered_map<string, vector<stack<string, vector<string> > > > hashMap = { { start, vector<stack<string, vector<string> > >(1, stack<string, vector<string> >(vector<string>(1, start))) },
         { end, vector<stack<string, vector<string> > >(1, stack<string, vector<string> >(vector<string>(1, end))) }
     };
     vector<vector<string> > vvs;
     findLadders(Head_set, Tail_set, dict, hashMap, vvs);
     return vvs;
 }
예제 #20
0
    vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) 
    {
        queue<string> q;
        bool endFlag = false;
        int sz = 0, wsz = beginWord.size();
        string curr, temp;
        q.push(beginWord);
        wordList.erase(beginWord);
        unordered_set<string> current;
        while(!q.empty() && !endFlag)
        {
            sz = q.size();
            for(int i = 0; i < sz; i++)
            {
                curr = q.front();
                q.pop();
                for(int j = 0; j < wsz; j++)
                {
                    for(char k = 'a'; k <= 'z'; k++)
                    {
                        temp = curr;
                        if(temp[j] == k)
                            continue;
                        temp[j] = k;
                        if(temp == endWord)
                        {
                            store[temp].insert(curr);
                            endFlag = true;
                        }
                        else if(wordList.find(temp) != wordList.end())
                        {
                            store[temp].insert(curr);
                            if(current.find(temp) == current.end())
                                q.push(temp);
                            current.insert(temp);
                        }
                    }
                }
            }
            for(auto it : current)
            {
                wordList.erase(it);
            }
            current.clear();
        }

        return createSequences(beginWord, endWord);
    }
예제 #21
0
 int ladderLength(string beginWord, string endWord, unordered_set<string> &wordList) {
     queue<string> q;
     //将endWord加入wordList
     wordList.insert(endWord);
     //从wordList中删除beginWord,避免重复使用词beginWord
     wordList.erase(beginWord);
     //BFS
     helper(beginWord, wordList, q);
     int ret = 2;
     while (!q.empty()) {
         int size = q.size();
         //处理这一层的所有节点
         for (int i = 0; i < size; i++) {
             string word = q.front();
             q.pop();
             //get end word
             if (word == endWord)
                 return ret;
             //BFS
             helper(word, wordList, q);
         }
         //节点全部处理完毕,层数加1
         ret++;
     }
     //没有找到结果,返回0
     return 0;
 }
예제 #22
0
 int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
     queue<pair<string,int>> q;
     q.push(make_pair(beginWord,1));
     while(q.empty() == false)
     {
         string cur = q.front().first;
         int step = q.front().second;
         q.pop();
         for(int i = 0; i < cur.length(); i++)
         {
             string cur_new = cur;
             for(int j = 'a'; j <= 'z'; j++) //comparing the current word with the word in wordDict costs more time than construct the next word
             {
                 cur_new[i] = j;
                 if(cur_new == endWord)
                 {
                     return ++step;
                 }
                 if(wordDict.find(cur_new) != wordDict.end())
                 {
                     q.push(make_pair(cur_new, step+1));
                     wordDict.erase(cur_new);
                 }
             }
         }
     }
     return 0;
 }
예제 #23
0
void find_dequeable(unordered_set<string>& ds, Deque<T> in,
		    Deque<T> dq = Deque<T>(), Deque<T> out = Deque<T>()) {

	if (in.empty() && dq.empty()) {	/* out is full */
		string setstr = out.str();
		ds.erase(setstr);
		return;
	}

	if (!in.empty()) {
		/* push front, back to deque */
		Deque<T> in_new1(in), in_new2(in);
		Deque<T> dq_new1(dq), dq_new2(dq);
		Deque<T> out_new1(out), out_new2(out);

		dq_new1.push_front(in_new1.pop_front());
		dq_new2.push_back(in_new2.pop_front());

		find_dequeable(ds, in_new1, dq_new1, out_new1);
		find_dequeable(ds, in_new2, dq_new2, out_new2);
	}

	if (!dq.empty()) {	/* pop front, back from deque */
		Deque<T> in_new3(in), in_new4(in);
		Deque<T> dq_new3(dq), dq_new4(dq);
		Deque<T> out_new3(out), out_new4(out);

		/* input does not change */
		out_new3.push_front(dq_new3.pop_front());
		out_new4.push_front(dq_new4.pop_back());

		find_dequeable(ds, in_new3, dq_new3, out_new3);
		find_dequeable(ds, in_new4, dq_new4, out_new4);
	}
}
예제 #24
0
    void addNextWord(string word, unordered_set<string>& wordList, queue<string>& toVisited) {
        wordList.erase(word);

        for(int i = 0; i < word.size(); ++i) {
            char ch = word[i];
            for(int j = 0; j < 26; ++j) {
                word[i] = (char)('a' + j);

                if(wordList.find(word) != wordList.end()) {
                    toVisited.push(word);
                    wordList.erase(word);
                }
            }
            word[i] = ch;
        }
    }
// 双向BFS搜索
// --------                     ----------
// |       |                    |        |
// |words1 |  <---------------> | words2 |
// |       |                    |        |
// ---------                    ----------   
// 不断地从两端向中心搜索,直至搜索到中间单词temp在另一个词袋中
int searchwithDoubleBFS(unordered_set<string>& words1, unordered_set<string>& words2,
	unordered_set<string>& dict, int level) {
	
	if (words1.empty()) return 0;		
	if (words1.size() > words2.size()) 
		return searchwithDoubleBFS(words2, words1, dict, level);
	
	unordered_set<string> words3;
	for (auto it = words1.begin(); it != words1.end(); ++it) {
		string word = *it;
		for (size_t i = 0; i < word.size(); ++i) {
			int ch = word[i];
			for (int k = 0; k < 26; ++k) {
				int ch2 = 'a' + k;
				if (ch2 != ch) {
					string temp = word;
					temp[i] = ch2;
					if (words2.find(temp) != words2.end()) {
						return level+1;
					} else {
						if (dict.find(temp) != dict.end()) {
							dict.erase(temp);
							words3.insert(temp);
						}
					}
					
				}
			}
		}
	}
	return searchwithDoubleBFS(words3, words2, dict, level+1);
}
예제 #26
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;
 }
예제 #27
0
void removeItem(unordered_set<int>& neighbor, int val)
{
	unordered_set<int>::iterator fiter = neighbor.find(val);
	if(fiter != neighbor.end()){
		neighbor.erase(fiter);
	}
}
예제 #28
0
 int ladderLength(string start, string end, unordered_set<string> &dict) {
     // special case
     if(start.compare(end)==0) return 1;
     
     // BFS
     int level = 1;
     vector<string> qu1, qu2;
     qu1.push_back(start);
     while(!qu1.empty()){
         // replace
         while(!qu1.empty()){
             string word = qu1[0];
             qu1.erase(qu1.begin());
             for(int i=0;i<word.size();i++){
                 for(char c='a';c<='z';c++){
                     if(c == word[i]) continue;
                     string tmp = word;
                     tmp[i] = c;
                     if(dict.find(tmp)!=dict.end()){
                         if(tmp.compare(end)==0) return level+1;
                         dict.erase(tmp);
                         qu2.push_back(tmp);
                     }
                 }
             }
         }
         // update
         qu1 = qu2;
         qu2.clear();
         level++;
     }
     
     // return
     return 0;
 }
예제 #29
0
 vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
     
     dict.insert(end);
     unordered_set<string> cur_lev;
     cur_lev.insert(start);
     unordered_set<string> next_lev;
     path.push_back(end);
     
     while (true){
         for (auto it : cur_lev){
             dict.erase(it);
         } //delete previous level words
         
         for (auto it : cur_lev){
             findDict2(it, dict, next_lev);
         }
         //find current level words
         
         if (next_lev.empty()){
             return res; }
         
         if (next_lev.count(end) != 0){ //if find end string
             output(start, end);
             return res;
         }
         cur_lev.clear();
         cur_lev = next_lev;
         next_lev.clear();
     }
     return res;
 }
예제 #30
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;
    }