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); }
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]; }
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); }
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]; }
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; }
//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); }
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; }
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; }
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; }
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); } } } }
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; }
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; }
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; }
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]; }
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]); } } } }
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; } }
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); } }
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; }
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(); } } }
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; }
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]; }
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; }
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; }
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]++; } }
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; }
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; }
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)); } } } }