Given an integer array nums of unique elements, return all possible subsets (the power set).
The solution set must not contain duplicate subsets. Return the solution in any order.
Example 1:
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
very basic backtracking
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution { public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> res = newArrayList<>(); dfs(res, nums, 0, newArrayList<Integer>()); return res; }
voiddfs(List<List<Integer>> res, int[] nums, int start, List<Integer> curr) { // bottom case res.add(newArrayList<Integer>(curr));
for (intend= start; end < nums.length; end++) { curr.add(nums[end]); dfs(res, nums, end + 1, curr); curr.remove(curr.size() - 1); } } }
vector<vector<int>> subsets(vector<int>& nums) { n = nums.size();
dfs(nums, 0);
return ans; }
voiddfs(vector<int>& nums, int start){ ans.push_back(path); for (int i = start; i < n; i++) { path.push_back(nums[i]); dfs(nums, i + 1); path.pop_back(); } } };
Time complexity: O(N×2N) to generate all subsets and then copy them into output list
Space complexity: O(N) to maintain curr, and are modifying curr in-place with backtracking; output array can be ignored
classSolution { public List<List<String>> partition(String s) { List<List<String>> res = newArrayList<>(); dfs(s, res, newArrayList<String>(), 0); return res; } voiddfs(String s, List<List<String>> res, List<String> curr, int start) { // bottom case if (start >= s.length()) res.add(newArrayList<String>(curr));
for (intend= start; end < s.length(); end++) { if (isPalindrome(s, start, end)) { // add it to the result list curr.add(s.substring(start, end + 1));
// recursion dfs(s, res, curr, end + 1);
// remove the last string in curr curr.remove(curr.size() - 1); } } }
booleanisPalindrome(String s, int l, int r) { while (l < r) { if (s.charAt(l) != s.charAt(r)) returnfalse; l++; r--; } returntrue; } }
// backtracking // using a current list to store palindrome strings // if curr reaches the length, add it back to the result list // backtrack: move the last palindrome string and continue dfs
classSolution{ publicbooleanexist(char[][] board, String word) { char[] w = word.toCharArray();
// search the cells one by one, if find, return for (inty=0; y < board.length; y++) { for (intx=0; x < board[y].length; x++) { if (dfs(board, y, x, w, 0)){ returntrue; } } }
returnfalse; }
privatebooleandfs(char[][] board, int y, int x, char[] word, int i) { // bottom case if (i == word.length) returntrue;
// boundaries if (y < 0 || x < 0 || y == board.length || x == board[y].length) returnfalse; if (board[y][x] != word[i]) returnfalse;
// mark the cell as completed charch= board[y][x]; board[y][x] = '#';
booleanexist= dfs(board, y, x+1, word, i+1) || dfs(board, y, x-1, word, i+1) || dfs(board, y+1, x, word, i+1) || dfs(board, y-1, x, word, i+1);
// unmark board[y][x] = ch;
return exist; } }
Time:
N: the number of cells, L: length of the word to be matched
O(N⋅3L)
3 directions to explore (since we won’t go back itself)
classSolution { public List<String> generateParenthesis(int n) { List<String> res = newArrayList<>(); backtrack(res, newStringBuilder(), 0, 0, n); return res; }
publicvoidbacktrack(List<String> res, StringBuilder cur, int open, int close, int max){ // bottom case // valid iif open == closed == n if (cur.length() == max * 2) res.add(cur.toString());
// only add open parenthesis if open < n if (open < max) { cur.append("("); backtrack(res, cur, open + 1, close, max); cur.deleteCharAt(cur.length() - 1); } // only add a closing parenthesis if closed < open if (close < open) { cur.append(")"); backtrack(res, cur, open, close + 1, max); cur.deleteCharAt(cur.length() - 1); } } }
time complexity: …
77. Combinations
https://leetcode.com/problems/combinations/
Given two integers n and k, return all possible combinations of k numbers chosen from the range [1, n]. You may return the answer in any order.
Example 1:
Input: n = 4, k = 2
Output: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = newArrayList<>(); dfs(n, k, res, newArrayList<Integer>(), 0); return res; } voiddfs(int n, int k, List<List<Integer>> res, List<Integer> curr, int start) { // base if (curr.size() == k) res.add(newArrayList<>(curr));
for (inti= start; i < n; i++) { curr.add(i + 1); dfs(n, k, res, curr, i + 1); curr.remove(curr.size() - 1); } } }
int n; vector<bool> st; // memo vector<vector<int>> ans; vector<int> path;
vector<vector<int>> permute(vector<int>& nums) { n = nums.size(); st = vector<bool>(n);
dfs(nums, 0);
return ans; }
voiddfs(vector<int>& nums, int u){ if (u == n) { ans.push_back(path); return; } for (int i = 0; i < n; i++) { // backtrack if (st[i]) continue; st[i] = true; path.push_back(nums[i]); dfs(nums, u + 1); st[i] = false; path.pop_back();