Skip to content

Commit 7f3de4a

Browse files
authored
Merge pull request #69 from Jer3myYu/java-solutions-backtracking
Java Chapter 14: Backtracking
2 parents 50e93f5 + 9bac83d commit 7f3de4a

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class CombinationsOfSumK {
5+
public List<List<Integer>> combinationsOfSumK(int[] nums, int target) {
6+
List<List<Integer>> res = new ArrayList<>();
7+
dfs(new ArrayList<>(), 0, nums, target, res);
8+
return res;
9+
}
10+
11+
private void dfs(List<Integer> combination, int startIndex, int[] nums, int target, List<List<Integer>> res) {
12+
// Termination condition: If the target is equal to 0, we found a combination
13+
// that sums to 'k'.
14+
if (target == 0) {
15+
res.add(new ArrayList<>(combination));
16+
return;
17+
}
18+
// Termination condition: If the target is less than 0, no more valid
19+
// combinations can be created by adding it to the current combination.
20+
if (target < 0) {
21+
return;
22+
}
23+
// Starting from start_index, explore all combinations after adding nums[i].
24+
for (int i = startIndex; i < nums.length; i++) {
25+
// Add the current number to create a new combination.
26+
combination.add(nums[i]);
27+
// Recursively explore all paths that branch from this new combination.
28+
dfs(combination, i, nums, target - nums[i], res);
29+
// Backtrack by removing the number we just added.
30+
combination.remove(combination.size() - 1);
31+
}
32+
}
33+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.util.ArrayList;
2+
import java.util.HashSet;
3+
import java.util.List;
4+
import java.util.Set;
5+
6+
public class FindAllPermutations {
7+
public List<List<Integer>> findAllPermutations(int[] nums) {
8+
List<List<Integer>> res = new ArrayList<>();
9+
backtrack(nums, new ArrayList<>(), new HashSet<>(), res);
10+
return res;
11+
}
12+
13+
private void backtrack(int[] nums, List<Integer> candidate, Set<Integer> used, List<List<Integer>> res) {
14+
// If the current candidate is a complete permutation, add it to the
15+
// result.
16+
if (candidate.size() == nums.length) {
17+
res.add(new ArrayList<>(candidate));
18+
return;
19+
}
20+
for (int num : nums) {
21+
if (!used.contains(num)) {
22+
// Add 'num' to the current permutation and mark it as used.
23+
candidate.add(num);
24+
used.add(num);
25+
// Recursively explore all branches using the updated
26+
// permutation candidate.
27+
backtrack(nums, candidate, used, res);
28+
// Backtrack by reversing the changes made.
29+
candidate.remove(candidate.size() - 1);
30+
used.remove(num);
31+
}
32+
}
33+
}
34+
}

java/Backtracking/FindAllSubsets.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class FindAllSubsets {
5+
public List<List<Integer>> findAllSubsets(int[] nums) {
6+
List<List<Integer>> res = new ArrayList<>();
7+
backtrack(0, new ArrayList<>(), nums, res);
8+
return res;
9+
}
10+
11+
private void backtrack(int i, List<Integer> currSubset, int[] nums, List<List<Integer>> res) {
12+
// Base case: if all elements have been considered, add the
13+
// current subset to the output.
14+
if (i == nums.length) {
15+
res.add(new ArrayList<>(currSubset));
16+
return;
17+
}
18+
// Include the current element and recursively explore all paths
19+
// that branch from this subset.
20+
currSubset.add(nums[i]);
21+
backtrack(i + 1, currSubset, nums, res);
22+
// Exclude the current element and recursively explore all paths
23+
// that branch from this subset.
24+
currSubset.remove(currSubset.size() - 1);
25+
backtrack(i + 1, currSubset, nums, res);
26+
}
27+
}

java/Backtracking/NQueens.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
public class NQueens {
5+
int res = 0;
6+
7+
public int nQueens(int n) {
8+
dfs(0, new HashSet<>(), new HashSet<>(), new HashSet<>(), n);
9+
return res;
10+
}
11+
12+
private void dfs(int r, Set<Integer> diagonalsSet, Set<Integer> antiDiagonalsSet, Set<Integer> colsSet, int n) {
13+
// Termination condition: If we have reached the end of the rows,
14+
// we've placed all 'n' queens.
15+
if (r == n) {
16+
res++;
17+
return;
18+
}
19+
for (int c = 0; c < n; c++) {
20+
int currDiagonal = r - c;
21+
int currAntiDiagonal = r + c;
22+
// If there are queens on the current column, diagonal or
23+
// anti-diagonal, skip this square.
24+
if (colsSet.contains(c) || diagonalsSet.contains(currDiagonal) || antiDiagonalsSet.contains(currAntiDiagonal)) {
25+
continue;
26+
}
27+
// Place the queen by marking the current column, diagonal, and
28+
// anti−diagonal as occupied.
29+
colsSet.add(c);
30+
diagonalsSet.add(currDiagonal);
31+
antiDiagonalsSet.add(currAntiDiagonal);
32+
// Recursively move to the next row to continue placing queens.
33+
dfs(r + 1, diagonalsSet, antiDiagonalsSet, colsSet, n);
34+
// Backtrack by removing the current column, diagonal, and
35+
// anti−diagonal from the hash sets.
36+
colsSet.remove(c);
37+
diagonalsSet.remove(currDiagonal);
38+
antiDiagonalsSet.remove(currAntiDiagonal);
39+
}
40+
}
41+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class PhoneKeypadCombinations {
7+
public List<Stirng> phoneKeypadCombinations(String digits) {
8+
Map<Character, String> keypadMap = new HashMap<>();
9+
keypadMap.put('2', "abc");
10+
keypadMap.put('3', "def");
11+
keypadMap.put('4', "ghi");
12+
keypadMap.put('5', "jkl");
13+
keypadMap.put('6', "mno");
14+
keypadMap.put('7', "pqrs");
15+
keypadMap.put('8', "tuv");
16+
keypadMap.put('9', "wxyz");
17+
List<String> result = new ArrayList<>();
18+
backtrack(0, new ArrayList<>(), digits, keypadMap, result);
19+
return result;
20+
}
21+
22+
private void backtrack(int i, List<Character> currCombination, String digits, Map<Character, String> keypadMap, List<String> result) {
23+
// Termination condition: if all digits have been considered, add the
24+
// current combination to the output list.
25+
if (currCombination.size() == digits.length()) {
26+
StringBuilder sb = new StringBuilder();
27+
for (char c: currCombination) {
28+
sb.append(c);
29+
}
30+
result.add(sb.toString());
31+
return;
32+
}
33+
for (char letter: keypadMap.get(digits.charAt(i)).toCharArray()) {
34+
// Add the current letter.
35+
currCombination.add(letter);
36+
// Recursively explore all paths that branch from this combination.
37+
backtrack(i + 1, currCombination, digits, keypadMap, result);
38+
// Backtrack by removing the letter we just added.
39+
currCombination.remove(currCombination.size() - 1);
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)