文章目录
- [一. 力扣 [1863. 找出所有子集的异或总和再求和](https://leetcode.cn/problems/sum-of-all-subset-xor-totals/description/)](#一. 力扣 1863. 找出所有子集的异或总和再求和)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [二. 力扣 [47. 全排列 II](https://leetcode.cn/problems/permutations-ii/description/)](#二. 力扣 47. 全排列 II)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [三. 力扣 [17. 电话号码的字母组合](https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/)](#三. 力扣 17. 电话号码的字母组合)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [四. 力扣 [22. 括号生成](https://leetcode.cn/problems/generate-parentheses/)](#四. 力扣 22. 括号生成)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
一. 力扣 1863. 找出所有子集的异或总和再求和
1. 题目解析
先找各个子集, 再求每个子集的异或结果, 最后相加
2. 算法原理
3. 代码
java
class Solution {
int ret = 0;
int path = 0;
public int subsetXORSum(int[] nums) {
dfs(nums, 0);
return ret;
}
void dfs(int[] nums, int pos) {
ret += path;
for (int i = pos; i < nums.length; i++) {
path ^= nums[i];
dfs(nums, i + 1);
// 回溯
path ^= nums[i];
}
}
}
二. 力扣 47. 全排列 II
1. 题目解析
2. 算法原理
3. 代码
java
class Solution {
List<List<Integer>> ret;
List<Integer> path;
boolean[] check;
public List<List<Integer>> permuteUnique(int[] nums) {
ret = new ArrayList<>();
path = new ArrayList<>();
check = new boolean[nums.length];
Arrays.sort(nums);
dfs(nums);
return ret;
}
void dfs(int[] nums) {
if (path.size() == nums.length) {
ret.add(new ArrayList(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (check[i] == false && (i == 0 || nums[i] != nums[i - 1] || check[i - 1] == true && nums[i] == nums[i - 1])) {
path.add(nums[i]);
check[i] = true;
dfs(nums);
// 回溯
path.remove(path.size() - 1);
check[i] = false;
}
}
}
}
三. 力扣 17. 电话号码的字母组合
1. 题目解析
2. 算法原理
3. 代码
java
class Solution {
String[] hash = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
List<String> ret;
StringBuilder path;
public List<String> letterCombinations(String digits) {
ret = new ArrayList<>();
path = new StringBuilder();
dfs(digits, 0);
return ret;
}
void dfs(String digits, int pos) {
if (pos == digits.length()) {
ret.add(path.toString());
return;
}
char[] tmp = hash[digits.charAt(pos) - '0'].toCharArray();
for (int i = 0; i < tmp.length; i++) {
path.append(tmp[i]);
// 继续往下一层递归
dfs(digits, pos + 1);
// 回溯
path.deleteCharAt(path.length() - 1);
}
}
}
四. 力扣 22. 括号生成
1. 题目解析
该题目最重要的点就是, 有效符号的定义:
1. 左右括号数量相等
2. 从头开始遍历的括号字符串中, 左括号数 ≥ 右括号数
2. 算法原理
3. 代码
java
class Solution {
int left = 0;
int right = 0;
List<String> ret = new ArrayList<>();
StringBuilder path = new StringBuilder();
int len;
public List<String> generateParenthesis(int n) {
len = n;
dfs();
return ret;
}
void dfs() {
if (right == len) {
ret.add(path.toString());
return;
}
// 添加左括号
if (left < len) {
path.append('(');
left++;
dfs();
// 回溯
path.deleteCharAt(path.length() - 1);
left--;
}
// 添加右括号
if (right < left) {
path.append(')');
right++;
dfs();
// 回溯
path.deleteCharAt(path.length() - 1);
right--;
}
}
}







