目录
1.二叉树中和为某一值的路径
1.1 题目描述
输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为
expectNumber的所有路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
1.2 回溯算法的一般步骤
1. 先添加值 (待选结果)
2. 再判定现有结果是否满足条件 (基于二叉树, 多叉树的穷举的过程, 在穷举的过程中, 要进行剪枝)
3. DFS (深度优先)
4. 回溯 (检测下一个)
1.3 解题思路
1.我们要明确从哪个节点开始.
2.深度优先遍历二叉树.
- 遍历的过程中我们需要一个一维数组 (ArrayList<Integer>)来添加某条路径上的所有结点的值 (待选结果), 每添加一个值, 我们对应的 expectNumber 就对应减去该结点的值
- 当该结点的左右子树都为空, 并且 expectNumber == 0 的时候, 此时我们需要一个二维数组 (ArrayList<ArrayList<Integer>>) 将其添加进去
1.4 代码实现
public void FindPathDFS(TreeNode root, int expectNumber, ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) {
if(root == null) {
return;
}
// 添加结果到待选结果中
list.add(root.val);
expectNumber -= root.val;
// 条件判断, 剪枝 (合法判定)
if(root.left == null && root.right == null && expectNumber == 0) {
result.add(new ArrayList<Integer>(list));
}
// DFS
FindPathDFS(root.left, expectNumber, result, list);
FindPathDFS(root.right, expectNumber, result, list);
// 回溯
list.remove(list.size() - 1);
}
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int expectNumber) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(root == null) {
return result;
}
ArrayList<Integer> list = new ArrayList<>();
FindPathDFS(root, expectNumber, result, list);
return result;
}
2. 字符串的排列
2.1 题目描述
输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。
示例1
输入:"ab"
返回值:["ab","ba"]
说明:返回["ba","ab"]也是正确的
2.2 解题思路
上图中基于三叉树的一个穷举过程, 然后再剪枝, 就得到了符合要求的排列组合.
于是这道题的全排列问题, 就可以看做如下三叉树型状态:
基本思路:
- 分别以 a, b, c 作为排列组合的起始字符, 然后 bc, ac, ab 再分别排列组合 (循环 + 递归)
- 这三次循环, 每排列组合完其中一种情况, 就需要进行回溯, 然后继续下一次排列组合.
- 注意每次准备将待选结果添加进结果集之前, 需要做去重处理, 以免出现类似于 "aa" 排列组合两次的情况.
2.3 代码实现
public void swap(char[] str, int start, int i) {
char tmp = str[start];
str[start] = str[i];
str[i] = tmp;
}
public boolean isExist(ArrayList<String> result, char[] str) {
return result.contains(String.valueOf(str));
}
public void PermutationHelper(char[] str, int start, ArrayList<String> result) {
if (start == str.length - 1) {
// 去重
if (!isExist(result, str)) {
result.add(new String(str));
}
return;
}
for (int i = start; i < str.length; i++) {
swap(str, start, i); // 以 i 对应的字符作为开始
PermutationHelper(str, start + 1, result); // [i+ 1, str.length- 1] 排列组合
swap(str, start, i); // 回溯
}
}
public ArrayList<String> Permutation(String str) {
ArrayList<String> list = new ArrayList<>();
if (str == null) {
return list;
}
char[] ch = str.toCharArray();
PermutationHelper(ch, 0, list);
return list;
}