Ejemplo n.º 1
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;
    }
Ejemplo n.º 2
0
shared_ptr<HashTables::BNode> HashTables::buildCannonicTree_helper(shared_ptr<BSTNode<int> > &n,
                             unordered_set<shared_ptr<BNode>, HashBNode, EqualBNode> &table) {
    if (!n) return nullptr;

    shared_ptr<BNode> left = buildCannonicTree_helper(n->left, table);
    shared_ptr<BNode> right = buildCannonicTree_helper(n->right, table);
    shared_ptr<BNode> newNode(new BNode(n->data, left, right));
    table.emplace(newNode);
    return newNode;
}
Ejemplo n.º 3
0
void reverseDFS(size_t idx) {
	if (visit[idx]) return;
	visit[idx] = true;
	
	for (auto next : revGraph[idx]) {
		reverseDFS(next);
	}
	
	selectedWord.emplace(sccId[idx]);
	sum++;
}
Ejemplo n.º 4
0
 void addClockReceiver(shared_ptr<Clocked> receiver)
 {
   clock_receivers.emplace(receiver);
 }
Ejemplo n.º 5
0
	/**
	* @param start, a string
	* @param end, a string
	* @param dict, a set of string
	* @return a list of lists of string
	*/
	vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
		vector<vector<string>> ans;
		/*
		in the pair, the vector contains all immediate and legal children of the node, int is the order of the node
		*/
		unordered_map<string, std::pair<vector<string>, int>> g;
		/*
		Put end on the dict to make sure we have an ending point on the graph
		*/
		dict.emplace(end);
		size_t len = start.length();
		char old_char = 0;
		string str, key;
		queue<string> q;
		q.push(start);
		while (false == q.empty()) {
			key = std::move(q.front()); q.pop();
			if (key == end) break;
			str = key;
			/*
			Since we use a huge structure to store graph info, g[key] should be created already when we set up its order during BFS.
			This is only for the string start as the key.
			BTW, for an existing key-value in unordered_map, try to emplace again will simply be ignored. In other words, newly given
			value will NOT replace the existing one.
			*/
			if (start == key)
				g.emplace(key, std::make_pair(vector<string>(), 0));
			for (size_t i = 0; i < len; ++i) {
				for (char j = 'a'; j <= 'z'; ++j) {
					if (j == str[i])continue;
					old_char = str[i];
					str[i] = j;
					if (dict.end() != dict.find(str)) {
						/*
						We will only process for the following two conditions:
						1. Node str has not been visited yet during a BFS. This can be confirmed by g.find(str) == g.end();
						2. Node str has been visited. However, the current key's order is one level above node str. In other
						words, according to the transform rule and common sense of a "shortest path", node key to node str
						is legit and str should be considered as key's legal child even though str has other parent(s).
						*/
						if (g.end() == g.find(str) || g[str].second == g[key].second + 1) {
							/*
							If g.find on str returns end, it means node str has not been visited yet
							*/
							if (g.end() == g.find(str)) {
								/*
								we should only push str to the queue if str hasn't be on the queue before.
								otherwise, we will introduce duplications onto the neighor list of str.
								*/
								q.push(str);
								g.emplace(str, std::make_pair(vector<string>(), g[key].second + 1));
							}
							/*
							however, we will put str onto key's neighor list even str is accessed before for an obvious reason:
							we need to find all possible routes even they may overlap in between (not completely though). In such
							scenario, str has multiple parents.
							*/
							g[key].first.push_back(str);
						}
					}
					str[i] = old_char;
				}
			}
		}
		vector<string> vec(dict.size() + 2);
		this->aux(ans, vec, g, start, end, 0);
		return ans;
	}
Ejemplo n.º 6
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);
							//very important trick here: keep track of where the neighbor
							//is from. This will improve the backtrack process since all
							//the string we trace back from end will lead us back to nothing but start,
							//we can avoid a lot of unnecessary check here
							toPush.emplace(neighbor);
						}
					}
				}
				que.pop();
			}
			/*
 * Here is what I don't understand. I firstly use following codes to find neighbors the current string, "front",
 * can "jump" to, by iterating the whole dict. I thought this should be faster than iterating chars in
 * the current string since the iterating the whole dict will take O(dict.size() * each level's size * length of string)
 * while above code takes O(26^length fo string) in time, which should be much greater than the first one.
 * However, I failed with the following case. Can anyone explain the reason, please?
				string front = que.front();
				dict.erase(front);
				if(front == end){
					endLevel = level;
					break;
				}
				else{
					for(unordered_set<string>::iterator itr = dict.begin(); itr != dict.end(); itr++){
						string neighbor = *itr;
						if(help2(neighbor, front)){
							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;
    }