voidbacktrack(TreeNode* root) { if(!root) return; // construct a string to update auto str = to_string(root->val); path += str; auto update_num = str.size(); // if it is a leaf node, we dont want a dangling tail '->' if(!root->left && !root->right) { paths.push_back(path); } else { path += "->"; update_num += 2;
backtrack(root->left); backtrack(root->right); } // resume its state path.erase(path.end() - update_num, path.end()); } };
classSolution { private: vector<int> path; vector<vector<int>> res; public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); backtrack(candidates.begin(), candidates.end(), target); return res; } template<typename It> voidbacktrack(It first, It last, int target) { if(target == 0) { res.emplace_back(path.begin(), path.end()); return; }
while(first < last) { // check if this decision is valid if(target - *first < 0) { // if first is not valid, due to the candidates are // sorted, all the elements after first cannot be // valid. break; }
// add the decision into the path path.push_back(*first); // dfs backtrack(first, last, target - *first); // cancel the decision path.pop_back(); // move to next choice ++first; } } };
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); backtrace(candidates.begin(), candidates.end(), target); return res; } template<typename It> voidbacktrace(It first, It last, int target) { // stop condition if(target == 0) { res.push_back(path); }
int pre = -1; while(first < last) { // if *first is the same with last one if(pre == *first) { ++first; continue; } pre = *first;
// check if the choice is valid if(target - *first < 0) break;
// add it into the path path.push_back(*first); backtrace(first + 1, last, target - *first); // cancel the choice path.pop_back(); // move first ++first; } } };
template<typename It> voidbacktrack(It first, It last) { if(ip.size() == 4 && first < last) { return; } // fill in all four parts for an IP // nothing left in the string if(ip.size() == 4 && first == last) { auto&& ip_str = string{}; auto it = ip.begin(); for(;it < --ip.end(); ++it) { ip_str += to_string(*it); ip_str += "."; } ip_str += to_string(*it); ips.emplace_back(move(ip_str)); }
for(auto it = first + 1; it <= last && it < first + 4; ++it) { auto part = string(first, it); auto num = stoi(part);
// make decisions // we could add left p if first < 3 if(state.first < p) { ++state.first; path += L_PARENTHESIS;
backtrack(); --state.first; path.pop_back(); }
// we could add right if only left > right if(state.first > state.second) { ++state.second; path += R_PARENTHESIS; backtrack(); --state.second; path.pop_back(); } } };
if(p.size() > 1 && p[1] == '*') { return // ignore .* and (LETTER)* isMatch(s, p.substr(2)) || // match the first letter of s with p, then forward s. ( // we have to make sure that s is not empty here (!s.empty() && (s[0] == p[0] || p[0] == '.')) && isMatch(s.substr(1), p) ); } else { return // p is not empty, then s must not be empty. !s.empty() && // match the first letters (s[0] == p[0] || p[0] == '.') && // match others isMatch(s.substr(1), p.substr(1)); } } };
classSolution { public: boolisMatch(string s, string p) { auto i = s.begin(); auto j = p.begin(); auto wc_i = s.end(); auto wc_j = p.end();
while(i != s.end()) { // if i and j are the same // of j is '?', just match if(*i == *j || '?' == *j) { ++i; ++j; } // if j is a wildcard, save its the pos for i & j elseif('*' == *j) { wc_i = i; wc_j = j; // move j forward, get the wildcard // ready for matching empty string ++j; } // if the pos for wc_j is not invalid, but we failed // in matching them, we have to backtrack elseif(wc_j != p.end()) { // move wc_i 1 pos forward // makes the wildcard to match more letters ++wc_i; i = wc_i; // get j back to the char after the wildcard j = wc_j + 1; } else { returnfalse; } }
// we have finished matching all char in s // we could accept the remaining chars in p are wildcards while(j != p.end() && *j == '*') ++j; return j == p.end(); } };
for(int i = 0; i < board.size(); ++i) { if(res) break; for(int j = 0; j < board.front().size(); ++j) { res = res || backtrack(board, 0, i, j); if(res) break; } } return res; }
boolbacktrack(const vector<vector<char>>& board, int n, int x, int y) { // we are on the wrong path if(n > word.size() - 1 || board[x][y] != word[n] || explored[x][y] != NOT_EXPLORED) { returnfalse; } // we found the word elseif(n == word.size() - 1 && board[x][y] == word[n]) { returntrue; }
// we are on the correct path, keep going else { explored[x][y] = EXPLORED;
bool res = false; // move up if(x > 0 && !res) { res = res || backtrack(board, n + 1, x - 1, y); } // move down if(x < board.size() - 1 && !res) { res = res || backtrack(board, n + 1, x + 1, y); } // move left if(y > 0 && !res) { res = res || backtrack(board, n + 1, x, y - 1); } // move right if(y < board.front().size() - 1 && !res) { res = res || backtrack(board, n + 1, x, y + 1); }
// create a list for roots auto roots = vector<TreeNode*>{};
// if it has no child if(N == 1) { auto root = new TreeNode{0}; roots.push_back(root); return roots; } for(int i = 1; i < N; i+=2) { // if it has two children for(auto left : backtrace(i)) { for(auto right : backtrace(N - 1 - i)) { auto root = new TreeNode{0}; root->left = left; root->right = right; roots.push_back(root); } } } return roots; } };