二叉树篇

重建二叉树 

先序遍历中「从 左边界+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. 树的子结构(先序遍历 + 包含判断,清晰图解) 

剑指 Offer 34. 二叉树中和为某一值的路径    

参考回溯算法详解

    /*

    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;

            }
        }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值