1.简而言之,一个集合里求组合就要用startIndex。
2.startIndex本身保证了组合的不同,需要求不同组合就要用startIndex;但从 i 开始还是从 i + 1 开始决定了组合元素能不能重复选。(39)
3.组内既不能重复选,也不能有重复组合,数组中还有重复元素,就要sort(40)
4.startIndex就是取了后面的不能取前面的所以保证不同的组合,但是排列不存在这个问题所以不用startIndex
5.切割就是组合
6.子集是收集路径的组合
112,113,257
combination 77,39,40,216,17
partitioning 131,93
subsets 78,90
permutations 46,47
51,37
491,332
112. Path Sum
Easy
Given the root
of a binary tree and an integer targetSum
, return true
if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum
.
A leaf is a node with no children.
class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {if(root == null){return false;}if(root.left == null && root.right == null){return root.val == targetSum;}boolean left = false;boolean right = false;if(root.left != null){left = hasPathSum(root.left , targetSum - root.val);}if(root.right != null){right = hasPathSum(root.right , targetSum - root.val);}return left || right;}
}
113. Path Sum II
Medium
Given the root
of a binary tree and an integer targetSum
, return all root-to-leaf paths where the sum of the node values in the path equals targetSum
. Each path should be returned as a list of the node values, not node references.
A root-to-leaf path is a path starting from the root and ending at any leaf node. A leaf is a node with no children.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> pathSum(TreeNode root, int targetSum) {dfs(root, targetSum);return ans;}private void dfs(TreeNode root , int targetSum){if(root == null){return;}path.add(root.val);if(root.left == null && root.right == null){if(root.val == targetSum){ans.add(new ArrayList(path));}}dfs(root.left , targetSum - root.val);dfs(root.right , targetSum - root.val);path.remove(path.size()-1);}
}
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> pathSum(TreeNode root, int targetSum) {dfs(root, targetSum);return ans;}private void dfs(TreeNode root , int targetSum){if(root == null){return;}path.add(root.val);if(root.left == null && root.right == null){if(root.val == targetSum){ans.add(new ArrayList(path));}}if(root.left != null){dfs(root.left , targetSum - root.val);path.remove(path.size()-1);}if(root.right != null){dfs(root.right , targetSum - root.val);path.remove(path.size()-1);}}
}
257. Binary Tree Paths
Easy
Given the root
of a binary tree, return all root-to-leaf paths in any order.
A leaf is a node with no children.
class Solution {public List<String> binaryTreePaths(TreeNode root) {List<String> res = new ArrayList<>();// 存最终的结果if (root == null) {return res;}List<Integer> paths = new ArrayList<>();// 作为结果中的路径traversal(root, paths, res);return res;}private void traversal(TreeNode root, List<Integer> paths, List<String> res) {paths.add(root.val);// 前序遍历,中// 遇到叶子结点if (root.left == null && root.right == null) {// 输出StringBuilder sb = new StringBuilder();// StringBuilder用来拼接字符串,速度更快for (int i = 0; i < paths.size() - 1; i++) {sb.append(paths.get(i)).append("->");}sb.append(paths.get(paths.size() - 1));// 记录最后一个节点res.add(sb.toString());// 收集一个路径return;}// 递归和回溯是同时进行,所以要放在同一个花括号里if (root.left != null) { // 左traversal(root.left, paths, res);paths.remove(paths.size() - 1);// 回溯}if (root.right != null) { // 右traversal(root.right, paths, res);paths.remove(paths.size() - 1);// 回溯}}}
class Solution {List<String> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<String> binaryTreePaths(TreeNode root) {dfs(root);return ans;}private void dfs(TreeNode root){if(root == null){return;}path.add(root.val);if(root.left == null && root.right ==null){StringBuilder sb = new StringBuilder();// StringBuilder用来拼接字符串,速度更快for (int i = 0; i < path.size() - 1; i++) {sb.append(path.get(i)).append("->");}sb.append(path.get(path.size() - 1));// 记录最后一个节点ans.add(sb.toString());// 收集一个路径}dfs(root.left);dfs(root.right);path.remove(path.size()-1);}
}
77. Combinations
Medium
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.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {backTrack(n, k, 1);return ans;}private void backTrack(int n, int k, int startIndex){if(path.size() == k){ans.add(new ArrayList(path));return;}for(int i = startIndex; i <= n; i++){path.add(i);backTrack(n, k, i + 1);path.remove(path.size()-1);}}
}
39. Combination Sum
Medium
Given an array of distinct integers candidates
and a target integer target
, return a list of all unique combinations of candidates
where the chosen numbers sum to target
. You may return the combinations in any order.
The same number may be chosen from candidates
an unlimited number of times. Two combinations are unique if the
frequency
of at least one of the chosen numbers is different.
The test cases are generated such that the number of unique combinations that sum up to target
is less than 150
combinations for the given input.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {backTrack(candidates, target, 0);return ans;}private void backTrack(int[] candidates, int target, int startIndex){if(target < 0 ){return;}if(target == 0){ans.add(new ArrayList(path));}for(int i = startIndex; i < candidates.length; i++){path.add(candidates[i]);backTrack(candidates, target-candidates[i], i);path.remove(path.size()-1);}}
}
40. Combination Sum II
Medium
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sum to target
.
Each number in candidates
may only be used once in the combination.
Note: The solution set must not contain duplicate combinations.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);backTrack(candidates,target,0);return ans;}private void backTrack(int[] candidates, int target, int startIndex){if(target == 0){ans.add(new ArrayList(path));return;}for(int i = startIndex; i < candidates.length; i++){if(target < 0){break;}if(i > startIndex && candidates[i] == candidates[i-1]){continue;}path.add(candidates[i]);backTrack(candidates, target - candidates[i], i + 1);path.remove(path.size()-1);}}
}
216. Combination Sum III
Medium
Find all valid combinations of k
numbers that sum up to n
such that the following conditions are true:
- Only numbers
1
through9
are used. - Each number is used at most once.
Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combinationSum3(int k, int n) {backTrack(k, n, 1, 0);return ans;}private void backTrack(int k, int n, int startIndex, int sum){if(path.size() == k){if(sum == n){ans.add(new ArrayList(path));}return;}for(int i = startIndex; i <= 9; i++){path.add(i);backTrack(k, n, i + 1, sum + i);path.remove(path.size()-1);}}
}
17. Letter Combinations of a Phone Number
Medium
Given a string containing digits from 2-9
inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.
A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
class Solution {List<String> ans = new ArrayList<>();public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0) {return ans;}Map<Character, String> phoneMap = new HashMap<Character, String>() {{put('2', "abc");put('3', "def");put('4', "ghi");put('5', "jkl");put('6', "mno");put('7', "pqrs");put('8', "tuv");put('9', "wxyz");}};backTrack(digits, phoneMap, 0);return ans;}StringBuilder path = new StringBuilder();private void backTrack(String digits, Map<Character, String> phoneMap, int num) {if (num == digits.length()) {ans.add(path.toString());return;}char ch = digits.charAt(num);String str = phoneMap.get(ch);for (int i = 0; i < str.length(); i++) {path.append(str.charAt(i));backTrack(digits, phoneMap, num + 1);path.deleteCharAt(path.length() - 1);}}
}
131. Palindrome Partitioning
Medium
Given a string s
, partition s
such that every substring of the partition is a palindrome
. Return all possible palindrome partitioning of s
.
Example 1:
Input: s = "aab" Output: [["a","a","b"],["aa","b"]]
class Solution {List<List<String>> ans = new ArrayList<>();List<String> path = new ArrayList<>();public List<List<String>> partition(String s) {backTrack(s, 0);return ans;}private void backTrack(String s , int startIndex){if(startIndex == s.length()){ans.add(new ArrayList(path));return;}for(int i = startIndex; i < s.length(); i++){String str = s.substring(startIndex, i + 1);if(isPalindrome(s, startIndex,i)){path.add(str);}else{continue;}backTrack(s, i + 1);path.remove(path.size() - 1);}}private boolean isPalindrome(String s, int startIndex, int endIndex){int i = startIndex;int j = endIndex;while(i <= j){if(s.charAt(i) != s.charAt(j)){return false;}i++;j--;}return true;}
}
93. Restore IP Addresses
Medium
A valid IP address consists of exactly four integers separated by single dots. Each integer is between 0
and 255
(inclusive) and cannot have leading zeros.
- For example,
"0.1.2.201"
and"192.168.1.1"
are valid IP addresses, but"0.011.255.245"
,"192.168.1.312"
and"192.168@1.1"
are invalid IP addresses.
Given a string s
containing only digits, return all possible valid IP addresses that can be formed by inserting dots into s
. You are not allowed to reorder or remove any digits in s
. You may return the valid IP addresses in any order.
Example 1:
Input: s = "25525511135" Output: ["255.255.11.135","255.255.111.35"]
class Solution {List<String> ans = new ArrayList<>();StringBuilder path = new StringBuilder();public List<String> restoreIpAddresses(String s) {backTrack(s, 0, 0);return ans;}private void backTrack(String s, int startIndex, int count){if(count == 4 && startIndex == s.length()){//不仅等于4还要用完所有数字ans.add(path.deleteCharAt(path.length()-1).toString());return;}if(count > 4){return;}for(int i = startIndex; i < s.length() && i < startIndex + 3; i++){String str = s.substring(startIndex, i + 1);if(isTrue(str)){int len = path.length();path.append(str).append(".");backTrack(s, i + 1, count + 1);path.setLength(len);}}}private boolean isTrue(String s){if(s.length()>1 && s.charAt(0) == '0'){return false;}int a = Integer.parseInt(s);return a >=0 && a <= 255;}
}
78. Subsets
Medium
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.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> subsets(int[] nums) {backTrack(nums, 0);return ans;}private void backTrack(int[] nums, int startIndex) {ans.add(new ArrayList<>(path));if (startIndex == nums.length) {return;}for (int i = startIndex; i < nums.length; i++) {path.add(nums[i]);backTrack(nums, i + 1);path.remove(path.size() - 1);}}
}
90. Subsets II
Medium
Given an integer array nums
that may contain duplicates, return all possible
subsets
(the power set).
The solution set must not contain duplicate subsets. Return the solution in any order.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> subsetsWithDup(int[] nums) {Arrays.sort(nums);backTrack(nums,0);return ans;}private void backTrack(int[] nums, int startIndex) {ans.add(new ArrayList<>(path));if (startIndex == nums.length) {return;}for (int i = startIndex; i < nums.length; i++) {if (i > startIndex && nums[i] == nums[i - 1]) {continue;}path.add(nums[i]);backTrack(nums, i + 1);path.remove(path.size() - 1);}}
}
46. Permutations
Medium
Given an array nums
of distinct integers, return all the possible permutations. You can return the answer in any order.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();boolean[] used;public List<List<Integer>> permute(int[] nums) {used = new boolean[nums.length];backTrack(nums);return ans;}private void backTrack(int[] nums) {if (path.size() == nums.length) {ans.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++) {if (used[i] == false) {path.add(nums[i]);used[i] = true;backTrack(nums);path.remove(path.size() - 1);used[i] = false;}}}
}
47. Permutations II
Medium
Given a collection of numbers, nums
, that might contain duplicates, return all possible unique permutations in any order.
class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> path = new ArrayList<>();boolean[] used;public List<List<Integer>> permuteUnique(int[] nums) {used = new boolean[nums.length];Arrays.sort(nums);backTrack(nums);return ans;}private void backTrack(int[] nums) {if (path.size() == nums.length) {ans.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++) {if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {//注意条件continue;}if (used[i] == false) {path.add(nums[i]);used[i] = true;backTrack(nums);used[i] = false;path.remove(path.size() - 1);}}}
}