0% found this document useful (0 votes)
2 views

Backtracking 2

The document discusses the backtracking algorithm, providing a basic description and template for its implementation. It includes various problems to practice, such as generating permutations, combinations, and subsets, along with code examples and explanations of how to adapt the algorithm for different scenarios. Additionally, it lists links to specific LeetCode problems for further practice.

Uploaded by

Kamal Kannan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Backtracking 2

The document discusses the backtracking algorithm, providing a basic description and template for its implementation. It includes various problems to practice, such as generating permutations, combinations, and subsets, along with code examples and explanations of how to adapt the algorithm for different scenarios. Additionally, it lists links to specific LeetCode problems for further practice.

Uploaded by

Kamal Kannan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

26/03/2022, 22:52 (1) Backtracking algorithm + problems to practice - LeetCode Discuss

Premium
(/) Explore(/explore/) Problems(/problemset/all/) InterviewNew Contest 🔈 LeetCode is hiring! Apply NOW.🔈
Store(https://leetcode.com/jobs/)(/subscribe?
(/contest/)
Discuss(/discuss/) 1

ref=nb_npl)
 Backtracking
Problems Discuss
Back(/tag/backtracking/discuss) Backtracking algorithm + problems to practice
(/A1exrebys) A1exrebys (/A1exrebys) 359 Last Edit: August 16, 2021 7:03 AM 3.3K VIEWS
39 Hi folks! I created a list of backtracking problems that can be useful to practice to solve more problems during interview / contest.
Backtracking algorithm is straightforward, but when it comes to real problems sometimes it is not obvious how we should tweak the
algorithm.
Let's check the basic description and template of backtracking algorithm:
Wikipedia: Backtracking is a general algorithm for finding solutions to some computational problems, notably
constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a candidate
("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution.

void dfs(arguments) {
if (condition == true) { // Condition when we should stop our exploration.
result.push_back(current);
return;
}
for (int i = num; i <= last; i++) {
current.push_back(i); // Explore candidate.
dfs(arguments);
current.pop_back(); // Abandon candidate.
}
}

One thing to remember before we can jump to some backtracking problems:


1. Permutation: can be thought of number of ways to order some input.
Example: permutations of ABCD, taken 3 at a time (24 variants): ABC, ACB, BAC, BCA, ...
2. Combnation: can be thought as the number of ways of selecting from some input.
Example: combination of ABCD, taken 3 at a time (4 variants): ABC, ABD, ACD, and BCD.
3. Subset: can be thought as a selection of objects form the original set.
Example: subset of ABCD: 'A', 'B', 'C', 'D,' 'A,B' , 'A,C', 'A,D', 'B,C', 'B,D', 'C,D', 'A,B,C', ...
From now let's start to apply this algorithm to solve some backtracking problems.
Permutations:
this set of problems related to generating (subset of) all possible permutations. Let's have a look at fist problem: Permutations
(https://leetcode.com/problems/permutations/)
In this problem we should return ALL the possible permutations from DISTINCT integer array.
void dfs(vector& nums, vector>& res,
vector<int>& cur, unordered_set<int>& used) {
if (cur.size() == nums.size()) { // (1)
res.push_back(cur);
return;
}
for (int i = 0; i < nums.size(); i++) {
if (!used.count(nums[i])) { // (2)
cur.push_back(nums[i]);
used.insert(nums[i]);
dfs(nums, res, cur, used);
cur.pop_back(); // (3)
used.erase(nums[i]);
}
}
}

You might notice that we change the original template for a bit:
1. We stop our exploration if the current array size is equal to the input array size, and we add current array to our result set.
2. As input array consist of district elements we can use unordered_set to track if this element has used before.
3. Backtrack: when we explore element we should remove it from vector and unordered_set.
Note: we can also use swap(), but it is easier to show the pattern using unordered_set.

https://leetcode.com/tag/backtracking/discuss/1405817/Backtracking-algorithm-%2B-problems-to-practice 1/4
26/03/2022, 22:52 (1) Backtracking algorithm + problems to practice - LeetCode Discuss
Another variation of the problem is Permutations II (https://leetcode.com/problems/permutations-ii/).
The only difference between first problem is that we MAY have DUPLICATES in the input array.
void dfs(vector& nums, vector& cur, vector>& res,
unordered_map& hmap) {
if (cur.size() == nums.size()) { // (1)
res.push_back(cur);
return;
}
for (auto& [num, freq] : hmap) { // (2)
if (freq == 0) continue; // (3)
freq--;
cur.push_back(num);
dfs(nums, cur, res, hmap);
cur.pop_back(); // (4)
freq++;
}
}

Let's check this algorithm and compare to the first problem:


1. Same as in the frist solution.
2. Instead of iteration through the original array, we are iterating using unordered_map. This unordered_map was build to have
element frequencies.
3. If element frequency is not equal to zero we can use it as potential candidate and we should decrease the frequency, so it won't
used again and again.
4. Backtrack: remove candidate from the current set of candidates (std::vector) and increase candidate frequency.
Note: we can solve this problem by sorting the input array and change if check in point number 3. We will have a look at this
approach in different problem.
Combinations: we are given two integers n and k, return ALL possible combinations of k numbers out of the range [1, n]. If you
want to solve this problem before jumping to the solution, here is the link: Combinations
(https://leetcode.com/problems/combinations/)
void dfs(int num, int last, int k, vector& cur,
vector<vector<int>>& res) {
if (cur.size() == k) { // (1)
res.push_back(cur);
return;
}
for (int i = num; i <= last; i++) { // (2)
cur.push_back(i);
dfs(i + 1, last, k, cur, res);
cur.pop_back();
}
}

Let's check what is the difference compared to earlier examples:


1. Almost the same as in the previous solutions, the key difference is that we need to put current set of elements to the result set
when the size will be equal to k.
2. The second difference is that starting point of iteration will be passed as an argument to each dfs() call.
3. Backtrack: remove element from the current set of elements. The same as in first example.
Let's next check another example: Combination Sum II (https://leetcode.com/problems/combination-sum-ii/). This time instead of using
hash table we will sort th elements before invoking dfs() for the first time.
We are given a collection of candidates and a target number, find ALL UNIQUE combinations in candidates where the candidate numbers
sum to target.
void dfs(int ind, vector& cur, vector>& res,
vector& cnd, int target) {
if (target == 0) { // (1)
res.push_back(cur);
return;
}
for (int i = ind; i < cnd.size(); i++) { // (2)
if (i > ind && cnd[i] == cnd[i - 1]) continue; // (3)
if (target - cnd[i] >= 0) {
cur.push_back(cnd[i]);
dfs(i + 1, cur, res, cnd, target - cnd[i]);
cur.pop_back(); // (4)
}
}
}

https://leetcode.com/tag/backtracking/discuss/1405817/Backtracking-algorithm-%2B-problems-to-practice 2/4
26/03/2022, 22:52 (1) Backtracking algorithm + problems to practice - LeetCode Discuss
Let's check for is the difference between others examples:
1. Here we don't need to check the current array size. If target result is equal to 0 then it means that we find a valid combination and
can add it to the current result set.
2. Almost the same as in earlier example, but we will be iterating untill we reach the end of the candidates.
3. Remember that we sort candidates array. One trick here i > ind is needed because we are only allowed to use each number in
candidates once.
4. Backtrack: the same as in earlier examples.
Subsets: we are given an integer array of unique elements, return all possible subsets (the power set). If you want to solve this
problem before check the solution, here is the link: Subsets (https://leetcode.com/problems/subsets/)
void dfs(int ind, vector& nums, vector& cur, vector>& res) {
res.push_back(cur); // (1)
for (int i = ind; i < nums.size(); i++) { // (2)
cur.push_back(nums[i]);
dfs(i + 1, nums, cur, res);
cur.pop_back(); // (3)
}
}

Let's check the steps again:


1. Now we are adding element to the result unconditionally. This is because we need to generate the subsets of integer array.
2. The same as in previous examples: we are using new element on each dfs() call.
3. Backtrack: the same as in previous example.
The implementation will be a bit different if the input array has duplicates Subsets II (https://leetcode.com/problems/subsets-ii/) ,
but we already know how to handle them using sorting:
void dfs(int ind, vector& cur, vector>& res,
vector& nums) {
res.push_back(cur);
for (int i = ind; i < nums.size(); i++) {
if (i > ind && nums[i] == nums[i - 1]) continue;
cur.push_back(nums[i]);
dfs(i + 1, cur, res, nums);
cur.pop_back();
}
}

For the last problem in this article let's check more complex / interesting problem that can be solved using backtracking: Word Squares
(https://leetcode.com/problems/word-squares/). We are given an array of unique strings words, we need to return all the word squares
you can build from words. Note: result word square should be symmetrical across its diagonal.
vector> wordSquares(vector& words) {
vector<vector<string>> res;
vector<string> cur;
unordered_map> hmap;
for (auto& w : words) {
for (int i = 0; i < w.size(); i++) hmap[w.substr(0, i)].push_back(w); // (1)
}
dfs(0, words[0].size(), res, cur, hmap);
return res;
}
void dfs(int ind, int sz, vector>& res, vector& cur,
unordered_map>& hmap) {
if (ind == sz) { // (2)
res.push_back(cur);
return;
}
string pref;
for (int i = 0; i < ind; i++) pref += cur[i][ind]; // (3)
for (auto& w : hmap[pref]) { // (4)
cur.push_back(w);
dfs(ind + 1, sz, res, cur, hmap);
cur.pop_back(); // (5)
}
}

The dfs() algorithm here is almost the same, but let's check the key points:
1. Prerequisite: we will use unordered_map to generate prefixes for each word before the first call of dfs().
2. If our current vector of strings has the same size as original list of words, then we should add it to our result set and stop exploring.

https://leetcode.com/tag/backtracking/discuss/1405817/Backtracking-algorithm-%2B-problems-to-practice 3/4
26/03/2022, 22:52 (1) Backtracking algorithm + problems to practice - LeetCode Discuss
3. One extra step compared to all others examples is that we are generating the prefix that is needed for the next word to satisfy the
problem requirement.
4. Iterating through the possible candidates that starts with the given prefix.
5. Backtrack: the same as for others problems.
Links to the problems above + some more problems to practice:
1. Permutations: https://leetcode.com/problems/permutations/ (https://leetcode.com/problems/permutations/)
2. Permutations II: https://leetcode.com/problems/permutations-ii/ (https://leetcode.com/problems/permutations-ii/)
3. Combinations: https://leetcode.com/problems/combinations/ (https://leetcode.com/problems/combinations/)
4. Combination Sum: https://leetcode.com/problems/combination-sum/ (https://leetcode.com/problems/combination-sum/)
5. Combination Sum II: https://leetcode.com/problems/combination-sum-ii/submissions/ (https://leetcode.com/problems/combination-
sum-ii/submissions/)
6. Combination Sum III: https://leetcode.com/problems/combination-sum-iii/ (https://leetcode.com/problems/combination-sum-iii/)
7. Subsets: https://leetcode.com/problems/subsets/submissions/ (https://leetcode.com/problems/subsets/submissions/)
8. Subsets II: https://leetcode.com/problems/subsets-ii/submissions/ (https://leetcode.com/problems/subsets-ii/submissions/)
9. Palindrome Partitioning: https://leetcode.com/problems/palindrome-partitioning/submissions/
(https://leetcode.com/problems/palindrome-partitioning/submissions/)
10. Generate parenthesis: https://leetcode.com/problems/generate-parentheses/ (https://leetcode.com/problems/generate-
parentheses/)
11. Letter Combinations: https://leetcode.com/problems/letter-combinations-of-a-phone-number/solution/
(https://leetcode.com/problems/letter-combinations-of-a-phone-number/solution/)
12. Word search: https://leetcode.com/problems/word-search/ (https://leetcode.com/problems/word-search/)
13. N-Queens: https://leetcode.com/problems/n-queens/ (https://leetcode.com/problems/n-queens/)
14. Sudoku solver: https://leetcode.com/problems/sudoku-solver/ (https://leetcode.com/problems/sudoku-solver/)
15. Word Squares: https://leetcode.com/problems/word-squares/ (https://leetcode.com/problems/word-squares/)

backtracking c++

Comments: 4 Best Most Votes Newest to Oldest Oldest to Newest

Type comment here... (Markdown is supported)

Post
(/hX_) hX_ (/hX_) 346 November 9, 2021 7:05 AM
Can you please explain or share some resources on how to calculate time complexity and space complexity of backtracking problems??
Thanks
3 Reply
(/suryakantpandey) suryakantpandey (/suryakantpandey) 3 Last Edit: August 27, 2021 9:37 AM
https://leetcode.com/list/9x0zfcir (https://leetcode.com/list/9x0zfcir) here is the link for list and it doesn't contain premium questions
2 Show 1 reply Reply
(/Symbolistic) Symbolistic (/Symbolistic) 33 December 2, 2021 9:46 AM
I just wanna say how much I appreciate you making this post, it helped make backtracking "click" for me in my head finally.
Thank you
1 Reply
(/rudeTool) rudeTool (/rudeTool) 46 August 23, 2021 8:23 PM
Can you create a list and share it?
1 Reply

Copyright © 2022 LeetCode


Help Center (/support) Jobs (/jobs) Bug Bounty (/bugbounty) Online Interview (/interview/) Students (/student) Terms (/terms) Privacy Policy (/privacy)
United States (/region)

https://leetcode.com/tag/backtracking/discuss/1405817/Backtracking-algorithm-%2B-problems-to-practice 4/4

You might also like