先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
面试题26. 树的子结构(先序遍历 + 包含判断,清晰图解)
参考回溯算法详解
/*
def backtrack(未探索区域, res, path):
if 未探索区域满足结束条件:
res.add(path) # 深度拷贝
return
for 选择 in 未探索区域当前可能的选择:
if 当前选择符合要求:
path.add(当前选择)
backtrack(新的未探索区域, res, path)
path.pop()//回溯
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<List<Integer>> list = new ArrayList<>();
List<Integer> res =new ArrayList<>();//中间结果
public List<List<Integer>> pathSum(TreeNode root, int target) {
get(root, target) ;
return list;
}
public void get(TreeNode root, int target){
if(root==null)
return;
res.add(root.val);
target-=root.val;
if(target==0&&root.left==null&&root.right==null)
list.add(new ArrayList(res));
else{
get(root.left,target);//7,7.left==null ,return
get(root.right,target);//7,7.righr==null;return;
}
res.remove(res.size()-1);//11.right,2
}
}
// //the second method;
// private ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
// public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
// backtracking(root, target, new ArrayList<>());
// return ret;
// }
// private void backtracking(TreeNode node, int target, ArrayList<Integer> path) {
// if (node == null)
// return;
// path.add(node.val);
// target -= node.val;
// if (target == 0 && node.left == null && node.right == null) {
// ret.add(new ArrayList<>(path));
// } else {
// backtracking(node.left, target, path);
// backtracking(node.right, target, path);
// }
// path.remove(path.size() - 1);
// }
// class Solution {
// boolean[] vis;
// public List<List<Integer>> permuteUnique(int[] nums) {
// List<List<Integer>> ans = new ArrayList<List<Integer>>();
// List<Integer> perm = new ArrayList<Integer>();
// vis = new boolean[nums.length];
// Arrays.sort(nums);
// backtrack(nums, ans, perm);
// return ans;
// }
// public void backtrack(int[] nums, List<List<Integer>> ans, List<Integer> perm) {
// if (perm.size() == nums.length) {
// ans.add(new ArrayList<Integer>(perm));
// return;
// }
// for (int i = 0; i < nums.length; ++i) {
// if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
// continue;
// }
// perm.add(nums[i]);
// vis[i] = true;
// backtrack(nums, ans, perm);
// perm.remove(perm.size()-1);
// vis[i] = false;
// }
// }
// }
class Solution {
boolean[] vis;
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> perm = new ArrayList<Integer>();
public List<List<Integer>> permuteUnique(int[] nums) {
vis = new boolean[nums.length];
Arrays.sort(nums);
backtrack(nums);
return ans;
}
public void backtrack(int[] nums) {
if (perm.size() == nums.length) {
ans.add(new ArrayList<Integer>(perm));
return;
}
for (int i = 0; i < nums.length; ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
/*
没有重复数字得全排列,这样写!
if (vis[i]) {
continue;
}
*/
perm.add(nums[i]);
vis[i] = true;
backtrack(nums);//prem.size()+1
perm.remove(perm.size()-1);
vis[i] = false;
}
}
}
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList();
List<Integer> path = new ArrayList();
Arrays.sort(candidates);
dfs(result, candidates, path, target, 0,0);
return result;
}
public void dfs(List<List<Integer>> result, int[] candidates, List<Integer> path, int target, int sum,int begin) {
if (sum == target) {
result.add(new ArrayList<>(path));
return;
}
for (int i = begin; i < candidates.length; i++) {
//要求不重复而不是i=0,[[2,2,3],[2,3,2],[3,2,2],[7]]
//排列组合就重复啦i=0[123][3,2,1]....
int rs=sum+candidates[i];
if(rs<=target) {//<=
path.add(candidates[i]);
//满足条件执行回溯。
dfs(result,candidates, path,target,rs,i);
path.remove(path.size()-1);//回溯,撤销当前操作
}
else
break;
}
}
}