算法之二叉树篇

91 阅读2分钟

🍓二叉树篇


 🍊题一:144. 二叉树的前序遍历

image.png

  

⭐️思路:

⭐️代码:

/**
 * 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 {
    public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res=new ArrayList<>();
    if(root==null) return res;
    Stack<TreeNode> stack=new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()){
        TreeNode node=stack.pop();
        res.add(node.val);
        if(node.right!=null){
            stack.push(node.right);
        }
        if(node.left!=null){
            stack.push(node.left);
        }
    }
    return res;
 }
}

 🍊题二:145. 二叉树的后序遍历

image.png

  

⭐️思路:

⭐️代码:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> res=new ArrayList<>();
    if(root==null) return res; //注意是返回res 而不是null
    Stack<TreeNode> stack=new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()){
    TreeNode node=stack.pop();
    res.add(node.val);
    if(node.left!=null){
        stack.push(node.left);
    }
    if(node.right!=null){
        stack.push(node.right);
    }
    }
    Collections.reverse(res);
    return res;
    }
}

 🍊题三: 94. 二叉树的中序遍历

  

⭐️思路:

⭐️代码:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res=new ArrayList<>();
    if(root==null) return res;
    Stack<TreeNode> stack=new Stack<>();
    while(root!=null||!stack.isEmpty()){
        while(root!=null){
            stack.push(root);
            root=root.left;
        }
        root=stack.pop();
        res.add(root.val);
        root=root.right;
    }
    return res;
    }
}

 🍊题四:114. 二叉树展开为链表

image.png

⭐️思路:

⭐️代码:

/**
 * 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 {
    public void flatten(TreeNode root) {
    if(root==null){
        return;
    }
    flatten(root.left);//递归拉平左右子树
    flatten(root.right);
    TreeNode left=root.left; //将左子树变成链表
    TreeNode right=root.right;
    TreeNode t=right;
    root.left=null;
    root.right=left; //将左子树作为右子树
    while(root.right!=null)root=root.right;//将原先的右子树接到当前右子树的末端
    root.right=right; //遍历完右节点后,将原先右子树接到如今的右节点上
    }
}

 🍊题五:101. 对称二叉树

    image.png

⭐️思路:

⭐️代码:

/**
 * 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 {
    public boolean isSymmetric(TreeNode root) {
    if(root==null)return true;
    return  check(root.left,root.right);
    }
    boolean check(TreeNode left,TreeNode right){
        if(left==null&&right==null)return true;
        if(left==null||right==null)return false;
        if(left.val!=right.val)return false;
        return check(left.left,right.right)&&check(left.right,right.left);
    }
}

🍎100. 相同的树

image.png

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
    if(p==null&&q==null) return true;
    if(p==null||q==null) return false;
    if(p.val!=q.val) return false;
    return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}

 🍊题六:104. 二叉树的最大深度

⭐️思路:

⭐️代码:

/**
 * 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 {
    public int maxDepth(TreeNode root) {
    if(root==null) return 0;
    int leftMax=maxDepth(root.left);
    int rightMax=maxDepth(root.right);
    return 1+Math.max(leftMax,rightMax);
    }
}

 🍊题六:226. 翻转二叉树

    image.png

⭐️思路:

⭐️代码:

/**
 * 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 {
    public TreeNode invertTree(TreeNode root) {
    if(root==null)return null;
    invertTree(root.left);
    invertTree(root.right);
    TreeNode t=root.left;
    root.left=root.right;
    root.right=t;
    return root;
    }
}

 🍊题七:538. 把二叉搜索树转换为累加树

    image.png

⭐️思路:

⭐️代码:

/**
 * 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 {
    int sum=0;
    public TreeNode convertBST(TreeNode root) {
    if(root!=null){
    convertBST(root.right);
    sum += root.val;
    root.val=sum;
    convertBST(root.left);
    }
    return root;
  }
}

 🍊题八:235. 二叉搜索树的最近公共祖先

    image.png

⭐️思路:

⭐️代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val>p.val&&root.val>q.val){
         return  lowestCommonAncestor(root.left,p,q);
        }
        if(root.val<p.val&&root.val<q.val){
         return  lowestCommonAncestor(root.right,p,q);
        }
        return root;
    }
}

 🍎236. 二叉树的最近公共祖先

image.png

⭐️思路:

⭐️代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if(root==null)return null;
    if(root.val==p.val||root.val==q.val) //若root遇到目标值,就返回目标值
    return root;    
    TreeNode left=lowestCommonAncestor(root.left,p,q);
    TreeNode right=lowestCommonAncestor(root.right,p,q);
    if(left==null) return right;//左子树没有p,q.返回该右节点找
    if(right==null)return left;
    return root;//该节点的左右子树都不会空,返回这个节点
    }
}

 🍊题九:617. 合并二叉树

image.png

⭐️思路:

⭐️代码:

/**
 * 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 {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
    if(root1==null) return root2;
    if(root2==null) return root1;
    root1.val+=root2.val;
    root1.left=mergeTrees(root1.left,root2.left);
    root1.right=mergeTrees(root1.right,root2.right);
    return root1;
    }
}

 🍊题九:

⭐️思路:

⭐️代码:

 🍊题九:

⭐️思路:

⭐️代码:

🍇关于构造树的题目

 🍇题九:654. 最大二叉树

image.png

⭐️思路:

设置递归函数 TreeNode build(int[] nums, int l, int r) 含义为从 nums 中的 [l, r][l,r] 下标范围进行构建,返回构建后的头结点。

当 l > rl>r 时,返回空节点,否则在 [l, r][l,r] 中进行扫描,找到最大值对应的下标 idx 并创建对应的头结点,递归构建 [l, idx - 1][l,idx−1] 和 [idx + 1, r][idx+1,r] 作为头节点的左右子树。

⭐️代码:

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
    return build(nums,0,nums.length-1);
    }
    public TreeNode build(int[] nums,int lo,int hi){
    if(lo>hi)return null;
    int index=lo;
    int max=-1;
    for(int i=lo;i<=hi;i++){
    if(max<nums[i]){
        max=nums[i];
        index=i;
     }
    }
    TreeNode root=new TreeNode(max);
    root.left=build(nums,lo,index-1);
    root.right=build(nums,index+1,hi);
    return root;
    }
}

 🍇题十:105. 从前序与中序遍历序列构造二叉树

⭐️思路:

image.png

⭐️代码:

/**
 * 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 {
    HashMap<Integer,Integer> valToIndex=new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    for(int i=0;i<inorder.length;i++){
        valToIndex.put(inorder[i],i);
    }
    return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    TreeNode build(int[] preorder,int preStar,int preEnd,
                   int[] inorder,int inStar,int indEnd){
                   if(preStar>preEnd)return null;
                   int rootVal=preorder[preStar];
                   int index=valToIndex.get(rootVal);
                   int leftsize=index-inStar;
                   //先构造当前节点
                   TreeNode root=new TreeNode(rootVal);
                   //递归构造左右子树
                   root.left=build(preorder,preStar+1,leftsize+preStar,
                                   inorder,inStar,index-1);
                   root.right=build(preorder,leftsize+preStar+1,preEnd,
                                    inorder,index+1,indEnd);
                   return root;
}
}

 🍇题十一:889. 根据前序和后序遍历构造二叉树

image.png

⭐️思路:

⭐️代码:

class Solution {
    // 存储 postorder 中值到索引的映射
    HashMap<Integer, Integer> valToIndex = new HashMap<>();

    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        for (int i = 0; i < postorder.length; i++) {
            valToIndex.put(postorder[i], i);
        }
        return build(preorder, 0, preorder.length - 1,
                    postorder, 0, postorder.length - 1);
    }

    // 定义:根据 preorder[preStart..preEnd] 和 postorder[postStart..postEnd]
    // 构建二叉树,并返回根节点。
    TreeNode build(int[] preorder, int preStart, int preEnd,
                   int[] postorder, int postStart, int postEnd) {
        if (preStart > preEnd) {
            return null;
        }
        if (preStart == preEnd) {
            return new TreeNode(preorder[preStart]);
        }

        // root 节点对应的值就是前序遍历数组的第一个元素
        int rootVal = preorder[preStart];
        // root.left 的值是前序遍历第二个元素
        // 通过前序和后序遍历构造二叉树的关键在于通过左子树的根节点
        // 确定 preorder 和 postorder 中左右子树的元素区间
        int leftRootVal = preorder[preStart + 1];
        // leftRootVal 在后序遍历数组中的索引
        int index = valToIndex.get(leftRootVal);
        // 左子树的元素个数
        int leftSize = index - postStart + 1;

        // 先构造出当前根节点
        TreeNode root = new TreeNode(rootVal);
        // 递归构造左右子树
        // 根据左子树的根节点索引和元素个数推导左右子树的索引边界
        root.left = build(preorder, preStart + 1, preStart + leftSize,
                postorder, postStart, index);
        root.right = build(preorder, preStart + leftSize + 1, preEnd,
                postorder, index + 1, postEnd - 1);
        return root;
    }
}

 🍊题十二:

⭐️思路:

⭐️代码:

 🍊题十三:

⭐️思路:

⭐️代码:

 🍊题九:

⭐️思路:

⭐️代码:

 🍊题九:

⭐️思路:

⭐️代码: