Leetcode(easy Tree)

Leetcode(easy Tree)

leetcode 简单的树的题目,记录一下自己的刷题过程

100. 相同的树

给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

/**
 * 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 isSameTree(TreeNode p, TreeNode q) {
        // myidea : 采用递归 比较当前传入的节点是否相同,如果相同,就继续递归遍历其右子树与左子树
        // 递归出口:如果传入的两个节点均不存在,则返回true,若其中一个为空,另外一个不为空,则返回false
        if(p == null && q == null) return true;
        if(p == null || q == null) return false;
        // 两者皆不为空,递归判断两者的左子树与两者的右子树
        return (p.val == q.val) && isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
        
    }
}

101. 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        // myidea: 也是采用递归,用一个额外的辅助函数,来进行判断
        return helper(root,root);
        
    }
    // 辅助函数,传入的参数为根节点,然后递归依次判断root1的左子树与root2的右子树是否相同
    public boolean helper(TreeNode root1,TreeNode root2){
        // 递归出口
        // 如果传入的两个树节点均不存在肯定是true
        if(root1 == null && root2 == null) return true;
        // 如果只有一个不存在,那么肯定是错误的 返回false
        if(root1 == null || root2 == null) return false;
        // 判断传入的树节点的值是否相同 递归判断root1的左子树与root2的右子树,以及root1的右子树与root2的左子树是否相同
        return (root1.val == root2.val) && helper(root1.left,root2.right) && helper(root1.right,root2.left);

    }
}

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        // myidea:采用递归
        // 递归出口:
        if(root == null) return 0;
        // 递归体
        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }
}

107. 二叉树的层次遍历 II

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        // myidea: 层次遍历么,很简单就是采用队列的方式进行就好了,首先先计算出来整个树的最大深度,然后记录为flag,每次倒着更新res就可以了
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        // 如果root为空的话
        if(root == null) return res;
        int flag = depth(root)-1;
        for(int i = 0;i<=flag;i++) res.add(new ArrayList<Integer>());
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i = 0;i<size;i++){
                TreeNode tmp = queue.poll();
                res.get(flag).add(tmp.val);
                if(tmp.left != null) queue.offer(tmp.left);
                if(tmp.right != null) queue.offer(tmp.right);
            }
            flag--;
        }
        return res;

    }
    // 返回一个树的最大深度
    public int depth(TreeNode root){
        if(root == null) return 0;
        return Math.max(depth(root.left),depth(root.right))+1;
    }
}

108. 将有序数组转换为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums,0,nums.length-1);
    }
    public TreeNode helper(int[] nums,int left,int right){
        if(left>right) return null;
        int mid = (left+right)/2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums,left,mid-1);
        root.right = helper(nums,mid+1,right);
        return root;
    }
}

110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root==null) return true;
        return Math.abs(depth(root.left)-depth(root.right))<2 && isBalanced(root.left) && isBalanced(root.right);
    }
    public int depth(TreeNode root){
        if(root==null) return 0;
        return Math.max(depth(root.left),depth(root.right)) + 1;
    }
}

111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。


112. 路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    boolean vaild;
    int pathSum;
    public boolean hasPathSum(TreeNode root, int sum) {
        // myidea : 采用递归+回溯
        if(root == null) return false;
        vaild = false;
        pathSum = 0;
        dfs(root,sum,pathSum);
        return vaild;

    }
    public void dfs(TreeNode root,int sum,int pathSum){
        // 递归出口
        if(root !=null && sum == pathSum + root.val && root.left == null && root.right == null){
            vaild = true;
            return;
        }
        if(root == null) return;
        // 递归
        dfs(root.left,sum,pathSum+root.val);
        dfs(root.right,sum,pathSum+root.val);
        // 回溯
        pathSum-=root.val;
        return;
    }
}

226. 翻转二叉树

翻转一棵二叉树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        // myidea:递归
        if(root == null) return root;
        TreeNode left = invertTree(root.left);
        TreeNode right = invertTree(root.right);
        root.left = right;
        root.right = left;
        return root;
    }

}

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

/**
 * 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) {
        // myidea
        if(root == null) return root;
        if(root.val == p.val || root.val == q.val) return root;
        if(p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right,p,q);
        if(p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left,p,q);
        return root;
    }
}

257. 二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<String> res;
    public List<String> binaryTreePaths(TreeNode root) {
        // myidea:用递归+回溯即可 
        res = new LinkedList<String>();
        dfs(root,"");
        return res;

    }
    public void dfs(TreeNode node,String str){
        if(node == null) return;
        // 到达叶子节点
        if(node.left == null && node.right == null){
            str = str + node.val;
            res.add(str);
            return;
        }
        String tmp = str;
        str = str + node.val + "->";
        // 没有到达叶子节点,就遍历其儿子节点
        dfs(node.left,str);
        dfs(node.right,str);
        // 回溯
        str = tmp;
    }
}

404. 左叶子之和

计算给定二叉树的所有左叶子之和。


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int res = 0;
    public int sumOfLeftLeaves(TreeNode root) {
        // myidea:递归+回溯
        dfs(root,0);
        return res;
    }
    // flag 标记位,1表示是左儿子,2表示右儿子
    public void dfs(TreeNode node,int flag){
        if(node == null) return;
        if(node.left == null && node.right == null){
            if(flag == 1) res+=node.val;
            return;
        }
        dfs(node.left,1);
        dfs(node.right,2);
    }
}

501. 二叉搜索树中的众数


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<Integer,Integer> map;
    public int[] findMode(TreeNode root) {
        // myidea:最简单的想法就是采用层次遍历,或者前,中,后序遍历,用map记录
        // 但是题目中的进阶不让使用额外的空间,这时候就需要考虑二叉搜索树的结构性质了
        // 首先先实现O(n)额外空间的实现方法
        map = new HashMap<Integer,Integer>();
        List<Integer> list = new ArrayList<Integer>();
        preOrder(root);
        int max = Integer.MIN_VALUE;
        // 找到最多数字出现的次数
        for(int key:map.keySet()) if(map.get(key) > max) max = map.get(key);
        for(int key:map.keySet()) if(map.get(key) == max) list.add(key);
        int[] res = new int[list.size()];
        for(int i = 0;i<list.size();i++) res[i] = list.get(i);
        return res;



    }
    public void preOrder(TreeNode node){
        if(node == null) return;
        if(!map.containsKey(node.val)) map.put(node.val,0);
        map.put(node.val,map.get(node.val)+1);
        preOrder(node.left);
        preOrder(node.right);

    }
}

530. 二叉搜索树的最小绝对差

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<Integer> record = new ArrayList<Integer>();
    public int getMinimumDifference(TreeNode root) {
        // myidea 二叉搜索树的中序遍历是一个有序数组
        inOrder(root);
        int res = Integer.MAX_VALUE;
        for(int i = 0;i<record.size()-1;i++) res = Math.min(res,record.get(i+1) - record.get(i));
        return res;

    }
    public void inOrder(TreeNode root){
        if(root == null) return;
        inOrder(root.left);
        record.add(root.val);
        inOrder(root.right);
    }
}

543. 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int diameterOfBinaryTree(TreeNode root) {
        // myidea 不就是根的左子树的高度与根的右子树的高度之和么?
        // 注意题目中说了 这个路径 可能穿过跟节点 也可能不穿过跟节点
        if(root == null) return 0;
        int res = Math.max((depth(root.left) + depth(root.right)),diameterOfBinaryTree(root.left));
        return Math.max(res,diameterOfBinaryTree(root.right));
    }
    public int depth(TreeNode root){
        if(root == null) return 0;
        return Math.max(depth(root.left) , depth(root.right))+1;
    }
}

559. N叉树的最大深度

给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public int maxDepth(Node root) {
        // myidea 采用层次遍历
        if(root == null) return 0;
        Queue<Node> queue = new LinkedList<Node>();
        int depth = 0;
        queue.offer(root);
        while(!queue.isEmpty()){
            depth++;
            int size = queue.size();
            for(int i = 0;i<size;i++){
                Node node = queue.poll();
                for(Node child:node.children) queue.offer(child);
            }
        }
        return depth;
        
    }
}

563. 二叉树的坡度

给定一个二叉树,计算 整个树 的坡度 。
一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。
整个树 的坡度就是其所有节点的坡度之和。

/**
 * 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<Integer> list = new ArrayList<Integer>();
    public int findTilt(TreeNode root) {
        // myidea:借助一个辅助list,记录每次左右子树的和的差值,然后利用dfs进行遍历
        if(root == null) return 0;
        calSum(root);
        int res = 0;
        for(int num:list) res+=num;
        return res;

    }
    // 计算整个树的和
    public int calSum(TreeNode root){
        if(root == null) return 0;
        int left = calSum(root.left);
        int right = calSum(root.right);
        list.add(Math.abs(left-right));
        return left+right+root.val;
    }
}

572. 另一个树的子树

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

/**
 * 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 isSubtree(TreeNode s, TreeNode t) {
        if(t == null) return true;
        if(s == null) return false;
        return isSame(s,t) || isSubtree(s.left,t) || isSubtree(s.right,t);
        
    }
    // 判断两棵树是否相同
    public boolean isSame(TreeNode s,TreeNode t){
        if(s == null && t == null) return true;
        if(s == null || t == null) return false;
        return (s.val == t.val) && isSame(s.left,t.left) && isSame(s.right,t.right); 
    }
}

589. N叉树的前序遍历

给定一个 N 叉树,返回其节点值的前序遍历。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    List<Integer> res = new ArrayList<Integer>();
    public List<Integer> preorder(Node root) {
        //myidea : 采用深度遍历的思想,就可以了
        if(root == null) return res;
        dfs(root);
        return res;
        
    }
    // 深度遍历
    public void dfs(Node root){
        if(root == null) return;
        res.add(root.val);
        for(Node child:root.children) dfs(child);
    }
}
// 采用迭代法
class Solution {
    public List<Integer> preorder(Node root) {
        // myidea:如果使用迭代法的话,需要使用额外的数据结构,这里使用额外的栈数据结构,
        Stack<Node> stack = new Stack<>();
        List<Integer> res = new LinkedList<>();
        if (root == null) {
            return res;
        }
        stack.push(root);
        while (!stack.isEmpty()) {
            Node node = stack.pop();
            res.add(node.val);
            // 将该节点所有的儿子从右到左压入栈中
            Collections.reverse(node.children);
            for (Node item : node.children) {
                stack.push(item);
            }
        }
        return res;
    }
}

590. N叉树的后序遍历

给定一个 N 叉树,返回其节点值的后序遍历。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    public List<Integer> postorder(Node root) {
        Stack<Node> stack = new Stack<>();
        LinkedList<Integer> res = new LinkedList<>();
        if (root == null) {
            return res;
        }

      stack.push(root);
      while (!stack.isEmpty()) {
          Node node = stack.pop();
          res.addFirst(node.val);
          for (Node item : node.children) {
              if (item != null) {
                  stack.push(item);    
              } 
          }
      }
      return res;
    }
}

606. 根据二叉树创建字符串

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public String tree2str(TreeNode t) {
        if(t==null)
            return "";
        if(t.left==null && t.right==null)
            return t.val+"";
        if(t.right==null)
            return t.val+"("+tree2str(t.left)+")";
        return t.val+"("+tree2str(t.left)+")("+tree2str(t.right)+")";   
    }
}

617. 合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if (t1 == null) {
            return t2;
        }
        if (t2 == null) {
            return t1;
        }
        TreeNode merged = new TreeNode(t1.val + t2.val);
        merged.left = mergeTrees(t1.left, t2.left);
        merged.right = mergeTrees(t1.right, t2.right);
        return merged;
    }
}

637. 二叉树的层平均值

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> averages = new ArrayList<Double>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            double sum = 0;
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                sum += node.val;
                TreeNode left = node.left, right = node.right;
                if (left != null) {
                    queue.offer(left);
                }
                if (right != null) {
                    queue.offer(right);
                }
            }
            averages.add(sum / size);
        }
        return averages;
    }
}

653. 两数之和 IV - 输入 BST

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        List < Integer > list = new ArrayList();
        inorder(root, list);
        int l = 0, r = list.size() - 1;
        while (l < r) {
            int sum = list.get(l) + list.get(r);
            if (sum == k)
                return true;
            if (sum < k)
                l++;
            else
                r--;
        }
        return false;
    }
    public void inorder(TreeNode root, List < Integer > list) {
        if (root == null)
            return;
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
}

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树不应该改变保留在树中的元素的相对结构(即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在唯一的答案。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

class Solution {
    public TreeNode trimBST(TreeNode root, int L, int R) {
        if (root == null) return root;
        if (root.val > R) return trimBST(root.left, L, R);
        if (root.val < L) return trimBST(root.right, L, R);

        root.left = trimBST(root.left, L, R);
        root.right = trimBST(root.right, L, R);
        return root;
    }
}

671. 二叉树中第二小的节点

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。
更正式地说,root.val = min(root.left.val, root.right.val) 总成立。
给出这样的一个二叉树,你需要输出所有节点中的第二小的值。如果第二小的值不存在的话,输出 -1 。

public int findSecondMinimumValue(TreeNode root) {
        if(root == null)
            return -1;
        return find(root, root.val);
    }

    /**
     * 按照题目描述
     * 找到和rootValue值不相同的最小值,与rootValue不相同的最小值其实就是第二小的值。
     */
    private int find(TreeNode x, int rootValue){
        if(x.val != rootValue) // 如果当前结点不等于根结点至,那么当x值为以x为根的最小的非rootValue的值
            return x.val;
        // 这之下都是 当前结点值为根结点值的情况
        if(x.left == null) // 递归到叶子结点 且其值为根结点值,说明没有找到第二小的值,返回失败标志-1。
            return -1;
        int leftMin = find(x.left, rootValue);
        int rightMin = find(x.right, rootValue);
        if(leftMin == -1)
            return rightMin;
        if(rightMin == -1)
            return leftMin;
        return Math.min(leftMin, rightMin);
    }

700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

class Solution {
  public TreeNode searchBST(TreeNode root, int val) {
    if (root == null || val == root.val) return root;

    return val < root.val ? searchBST(root.left, val) : searchBST(root.right, val);
  }
}

783. 二叉搜索树节点最小距离

给定一个二叉搜索树的根节点 root,返回树中任意两节点的差的最小值。

class Solution {
    Integer prev, ans;
    public int minDiffInBST(TreeNode root) {
        prev = null;
        ans = Integer.MAX_VALUE;
        dfs(root);
        return ans;
    }

    public void dfs(TreeNode node) {
        if (node == null) return;
        dfs(node.left);
        if (prev != null)
            ans = Math.min(ans, node.val - prev);
        prev = node.val;
        dfs(node.right);
    }
}

872. 叶子相似的树

class Solution {
    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        List<Integer> leaves1 = new ArrayList();
        List<Integer> leaves2 = new ArrayList();
        dfs(root1, leaves1);
        dfs(root2, leaves2);
        return leaves1.equals(leaves2);
    }

    public void dfs(TreeNode node, List<Integer> leafValues) {
        if (node != null) {
            if (node.left == null && node.right == null)
                leafValues.add(node.val);
            dfs(node.left, leafValues);
            dfs(node.right, leafValues);
        }
    }
}

897. 递增顺序查找树

给你一个树,请你 按中序遍历 重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。

class Solution {    
    public TreeNode increasingBST(TreeNode root) {
        List<Integer> vals = new ArrayList();
        inorder(root, vals);
        TreeNode ans = new TreeNode(0), cur = ans;
        for (int v: vals) {
            cur.right = new TreeNode(v);
            cur = cur.right;
        }
        return ans.right;
    }

    public void inorder(TreeNode node, List<Integer> vals) {
        if (node == null) return;
        inorder(node.left, vals);
        vals.add(node.val);
        inorder(node.right, vals);
    }
}

class Solution {
    TreeNode cur;
    public TreeNode increasingBST(TreeNode root) {
        TreeNode ans = new TreeNode(0);
        cur = ans;
        inorder(root);
        return ans.right;
    }

    public void inorder(TreeNode node) {
        if (node == null) return;
        inorder(node.left);
        node.left = null;
        cur.right = node;
        cur = node;
        inorder(node.right);
    }
}

938. 二叉搜索树的范围和

给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和。
二叉搜索树保证具有唯一的值。

class Solution {
    int ans;
    public int rangeSumBST(TreeNode root, int L, int R) {
        ans = 0;
        dfs(root, L, R);
        return ans;
    }

    public void dfs(TreeNode node, int L, int R) {
        if (node != null) {
            if (L <= node.val && node.val <= R)
                ans += node.val;
            if (L < node.val)
                dfs(node.left, L, R);
            if (node.val < R)
                dfs(node.right, L, R);
        }
    
class Solution {
    public int rangeSumBST(TreeNode root, int L, int R) {
        int ans = 0;
        Stack<TreeNode> stack = new Stack();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (node != null) {
                if (L <= node.val && node.val <= R)
                    ans += node.val;
                if (L < node.val)
                    stack.push(node.left);
                if (node.val < R)
                    stack.push(node.right);
            }
        }
        return ans;
    }
}

965. 单值二叉树

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。

class Solution {
    List<Integer> vals;
    public boolean isUnivalTree(TreeNode root) {
        vals = new ArrayList();
        dfs(root);
        for (int v: vals)
            if (v != vals.get(0))
                return false;
        return true;
    }

    public void dfs(TreeNode node) {
        if (node != null) {
            vals.add(node.val);
            dfs(node.left);
            dfs(node.right);
        }
    }
}

993. 二叉树的堂兄弟节点

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。
如果二叉树的两个节点深度相同,但父节点不同,则它们是一对堂兄弟节点。

class Solution {
    Map<Integer, Integer> depth;
    Map<Integer, TreeNode> parent;

    public boolean isCousins(TreeNode root, int x, int y) {
        depth = new HashMap();
        parent = new HashMap();
        dfs(root, null);
        return (depth.get(x) == depth.get(y) && parent.get(x) != parent.get(y));
    }

    public void dfs(TreeNode node, TreeNode par) {
        if (node != null) {
            depth.put(node.val, par != null ? 1 + depth.get(par.val) : 0);
            parent.put(node.val, par);
            dfs(node.left, node);
            dfs(node.right, node);
        }
    }
}

1022. 从根到叶的二进制数之和

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int ans = 0;    // 存放结果
    int mod = 1000000000 + 7;   // 用作取模
    public int sumRootToLeaf(TreeNode root) {
        helper(root, 0);
        return ans % mod;
    }

    public void helper(TreeNode root, int sum) {
        if (root != null) {      
            sum = sum * 2 + root.val;   
            if (root.left == null && root.right == null) {
                ans += sum;     // 到达叶子节点,得到一个和,加到结果上
            } else {    // 没有到达叶子节点,继续递归
                helper(root.left, sum);
                helper(root.right, sum);
            }
        }
    }

}

剑指 Offer 27. 二叉树的镜像

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode mirrorTree(TreeNode root) {
        if(root == null) return root;
        TreeNode left = mirrorTree(root.right);
        TreeNode right = mirrorTree(root.left);
        root.left = left;
        root.right = right;
        return root;
    }
}

剑指 Offer 28. 对称的二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return isMirror(root,root);
    }
    public boolean isMirror(TreeNode root1,TreeNode root2){
        if(root1 == null && root2 == null) return true;
        if(root1 == null || root2 == null) return false;
        return (root1.val == root2.val) && isMirror(root1.left,root2.right) && isMirror(root1.right,root2.left);
    }
}

剑指 Offer 32 - II. 从上到下打印二叉树 II

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
同上

剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第k大的节点。

class Solution {
    List<Integer> list = new ArrayList<Integer>();
    public int kthLargest(TreeNode root, int k) {
        inOrder(root);
        return list.get(list.size() - k);
    }
    public void inOrder(TreeNode root){
        if(root == null) return;
        inOrder(root.left);
        list.add(root.val);
        inOrder(root.right);

    }
}

剑指 Offer 55 - I. 二叉树的深度

同上

剑指 Offer 55 - II. 平衡二叉树

同上

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

同上

剑指 Offer 68 - II. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
在这里插入图片描述

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if(left == null) return right;
        if(right == null) return left;
        return root;
    }
}

面试题 04.02. 最小高度树

就是构造二叉搜索树 同上

面试题 04.04. 检查平衡性

同上

面试题 17.12. BiNode

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode convertBiNode(TreeNode root) {
        TreeNode head = new TreeNode(0);// 单链表的头指针哨兵
        // 开始中序遍历
        inorder(root,head);
        return head.right;
    }

    private TreeNode inorder(TreeNode root,TreeNode prev){
        if (root != null){
            prev = inorder(root.left,prev);
            root.left = null;
            prev.right = root;
            prev = root;
            prev = inorder(root.right,prev);
        }
        return prev;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值