leetcode 二叉树相关

求根节点到叶节点的数字之和

/**
 * 129. Sum Root to Leaf Numbers
 * 求根节点到叶节点的数字之和
 * 递归出口,叶节点
 * @param root
 * @return
 */
public int sumNumbers(TreeNode root) {

    return  sumTree(root,0);
}

public int sumTree(TreeNode root,int sum) {

    if (root == null) {
        return 0;
    }
    if (root.left== null && root.right == null) {
        return sum*10 + root.val;
    }

    return sumTree(root.left,root.val +sum*10)+sumTree(root.right,sum*10+root.val);
}

Sum II 求根节点到叶节点的路径和为sum的所有的路径

  /**
 * 113. Path Sum II 求根节点到叶节点的路径和为sum的所有的路径
 * @param root
 * @param sum
 * @return
 */
public List<List<Integer>> pathSum(TreeNode root, int sum) {

    List<List<Integer>> result = new ArrayList<>();
    if (root == null) {
        return result;
    }

    if (root.left == null && root.right == null && sum == root.val) {
        List<Integer> r = new ArrayList<>();
        r.add(root.val);
        result.add(r);
    }

    List<List<Integer>> leftR = pathSum(root.left,sum - root.val);
    for (List<Integer> list: leftR) {

        list.add(0,root.val);
        result.add(list);
    }

    List<List<Integer>> rightR = pathSum(root.right,sum - root.val);
    for (List<Integer> list: rightR) {

        list.add(0,root.val);
        result.add(list);
    }
    return result;
}

求二叉树中的所有的从根节点到叶节点的路径

 /**
 * 257
 * 求二叉树中的所有的从根节点到叶节点的路径
 *
 * @param root
 * @return
 */
public List<String> binaryTreePaths(TreeNode root) {

    List<String> result= new ArrayList<>();
    if (root == null) {
        return result;
    }
    if (root.left== null && root.right == null) {
        result.add(root.val+"");
    }

    List<String> leftR = binaryTreePaths(root.left);
    for (String leftStr : leftR) {
        result.add(root.val+"->"+leftStr);
    }

    List<String> rightR = binaryTreePaths(root.right);
    for (String rightStr : rightR) {
        result.add(root.val+"->"+rightStr);
    }
    return result;
}

给出一颗二叉树和一个数值sum,求是否存在从根节点到叶子节点的路径使得节点和为sum

 /**
 * 112 给出一颗二叉树和一个数值sum,求是否存在从根节点到叶子节点的路径使得节点和为sum
 * 思路:
 * 使用递归思想,root到叶节点的和为sum是否存在也即要求root的
 * 左右子树是否存在到叶节点的路径之和为sum-root.val
 *
 * 注意:
 * 递归中止条件: 根节点到叶子节点的路径之和为sum
 * 递归过程,在左右子树中去找是否存在递归条件
 * @param root
 * @param sum
 * @return
 */
public boolean hasPathSum(TreeNode root, int sum) {

    if (root == null) {
        return false;
    }
    if (root.left == null && root.right == null) {
        return root.val == sum;
    }
    return hasPathSum(root.left,sum - root.val) || hasPathSum(root.right,sum - root.val);
}

求二叉树中所有左叶子节点的和

/**
* 404
* 求二叉树中所有左叶子节点的和
* 递归出口:左叶子节点(左右子树为空)
*思路:
* 当前节点的左孩子节点如果是叶节点,那么返回该节点的左孩子节点+右子树的左叶节点的和
* 否则,去左右子树中去寻找
*
* @param root
* @return
*/
public int sumOfLeftLeaves(TreeNode root) {

    if (root == null) {
        return 0;
    }

    if (root.left != null && root.left.left == null && root.left.right == null) {
        return root.left.val + sumOfLeftLeaves(root.right);
    }
    return sumOfLeftLeaves(root.left)+ sumOfLeftLeaves(root.right);
}

检查一课二叉树是不是对称的

 /**
 * 101
 * 检查一课二叉树是不是对称的
 * 思路:
 * 1.用一个双端队列来实现
 * 首先将根节点的左子树放到队列的头部,右子树放到尾部
 * 然后遍历队列:
 *      取出头部和尾部的节点
 *          如果头部节点和尾部节点值相等,那么将头部节点的左右子树分别放入队列的头部,尾部节点的左右子树分别放入队列的尾部
 *          如果不想等,直接返回
 * 遍历结束之后,如果队列里面的元素是空的,说明该树是对称的
 *
 * 2.用递归来实现
 * @param root
 * @return
 */
public static boolean isSymmetric(TreeNode root) {

    return root == null || isSymmetric1(root.left,root.right);
}

public static boolean isSymmetric1(TreeNode left,TreeNode right) {
    int result = (left == null? 1:0) + (right == null? 1: 0);
    if(result == 2) {
        return true;
    }else if (result == 1) {
        return false;
    }else {
        return left.val == right.val && isSymmetric1(left.left,right.right) && isSymmetric1(left.right,right.left);
    }
}

public static boolean isSymmetric1(TreeNode root) {

    if (root == null) {
        return true;
    }
    LinkedList<TreeNode> queue = new LinkedList<>();
    queue.addFirst(root.left);
    queue.addLast(root.right);
    while (!queue.isEmpty()) {

        TreeNode first = queue.pollFirst();
        TreeNode last = queue.pollLast();
        if (first == null && last == null) {
            continue;
        }else if (first == null || last == null) {
            return false;
        }else {
            if (first.val ==  last.val) {

                queue.addFirst(first.right);
                queue.addFirst(first.left);

                queue.addLast(last.left);
                queue.addLast(last.right);
            }else {
                return false;
            }
        }

    }
    return queue.isEmpty();
}

判断两棵树是否相等

 /**
 * 100 判断两棵树是否相等
 * @param p
 * @param q
 * @return
 */
public boolean isSameTree(TreeNode p, TreeNode q) {

    if (p== null && q == null) {
        return true;
    }

    if (p != null && q != null && p.val == q.val) {
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
    return false;
}

求二叉树的最大深度

/**
* 求二叉树的最大深度
* 思路:
* 递归求解左右子树的最大深度,然后返回最大值即可
* @param root
* @return
*/
public static int maxDepth(TreeNode root) {

      if (root == null) {

          return 0;
      }

      return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}

求二叉树的最小深度

/**
 * 求二叉树的最小深度
 * 思路:
 * 需要考虑节点的下面的情况:
 *          只有左子树,
 *          只有右子树
 *          既有左子树也有右子树
 * @param root
 * @return
 */
public int minDepth(TreeNode root) {

    if (root == null) {
        return 0;
    }
    if (root.right == null) {
        return minDepth(root.left) + 1;
    }

    if (root.left == null) {
        return minDepth(root.right) + 1;
    }
    return Math.min(minDepth(root.left),minDepth(root.right))+1;
}

Binary Tree Right Side View

/**
 * 199. Binary Tree Right Side View
 * 思路:
 * 取每一层的最右边的节点!
 * 1.可以通过队列获取到每一层的节点,然后剥离每一层的最后一个节点!
 * 2.也可以通过栈来实现,每次将左孩子先入栈!判断节点的层级和结果数组大小的
 * 关系来决定要不要将节点放入结果集
 * @param root
 * @return
 */

public List<Integer> rightSideView1(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if(root == null){
        return result;
    }

    Stack<LevelNode> stack = new Stack();
    stack.push(new LevelNode(root,1));
    while(!stack.isEmpty()){

        LevelNode levelNode =  stack.pop();
        if (levelNode.level > result.size()) {
            result.add(levelNode.node.val);
        }

        if (levelNode.node.left != null) {
            stack.add(new LevelNode(levelNode.node.left,levelNode.level+1));
        }

        if (levelNode.node.right != null) {
            stack.add(new LevelNode(levelNode.node.right,levelNode.level+1));
        }
    }

    return result;
}

public List<Integer> rightSideView(TreeNode root) {

    List<List<Integer>> lists = new ArrayList<>();

    List<Integer> result = new ArrayList<>();
    if (root == null) {
        return result;
    }

    Queue<LevelNode> queue = new ArrayDeque<>();
    queue.add(new LevelNode(root,0));
    while (!queue.isEmpty()) {

        LevelNode levelNode = queue.poll();
        List<Integer> nodeList = null;
        if (levelNode.level == lists.size()) {
            nodeList = new ArrayList<>();
            lists.add(nodeList);
        }else {
            nodeList = lists.get(levelNode.level);
        }
        nodeList.add(levelNode.node.val);
        if (levelNode.node.left != null) {
            queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
        }

        if (levelNode.node.right != null) {
            queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
        }
    }

    for(List<Integer> tempList:lists){
        result.add(tempList.get(tempList.size() - 1));
    }
    return result;
}

Binary Tree Zigzag Level Order Traversal

 /**
 * 103. Binary Tree Zigzag Level Order Traversal
 * 从顶层向下“之”字形打印二叉树
 *
 * 思路:
 * 在队列的基础上,改变父节点的左右孩子的入队列的次序!
 *
 */
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {

    List<List<Integer>> lists = new ArrayList<>();

    if (root == null) {
        return lists;
    }

    boolean reverseFlag = false;
    Queue<LevelNode> queue = new ArrayDeque<>();
    queue.add(new LevelNode(root,0));
    while (!queue.isEmpty()) {

        LevelNode levelNode = queue.poll();
        List<Integer> nodeList = null;
        if (levelNode.level == lists.size()) {
            nodeList = new ArrayList<>();
            lists.add(nodeList);
        }else {
            nodeList = lists.get(levelNode.level);
        }

        if (levelNode.level == lists.size()) {
            reverseFlag = !reverseFlag;
        }

        nodeList.add(levelNode.node.val);




        if (reverseFlag) {

            if (levelNode.node.right != null) {
                queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
            }

            if (levelNode.node.left != null) {
                queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
            }
        }else {
            if (levelNode.node.left != null) {
                queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
            }

            if (levelNode.node.right != null) {
                queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
            }
        }

    }
    return lists;
}

Binary Tree Level Order Traversal II

 /**
 * 107. Binary Tree Level Order Traversal II

public List<List<Integer>> levelOrderBottom(TreeNode root) {

    List<List<Integer>> lists = new ArrayList<>();

    if (root == null) {
        return lists;
    }

    Queue<LevelNode> queue = new ArrayDeque<>();
    queue.add(new LevelNode(root,0));
    while (!queue.isEmpty()) {

        LevelNode levelNode = queue.poll();
        List<Integer> nodeList = null;
        if (levelNode.level == lists.size()) {
            nodeList = new ArrayList<>();
            //将每一层放到数组的首个位置
            lists.add(0,nodeList);
        }else {
            //取出首个位置层的对应节点
            nodeList = lists.get(0);
        }
        nodeList.add(levelNode.node.val);
        if (levelNode.node.left != null) {
            queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
        }

        if (levelNode.node.right != null) {
            queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
        }
    }
    return lists;
}

利用队列实现层序遍历二叉树

 /**
 * 102. Binary Tree Level Order Traversal
 * 利用队列实现层序遍历二叉树
 * 思路:
 * 1.将根节点入队列
 * 2.如果队列非空,执行以下步骤:
 *   a.出队列取得队列的节点,访问该节点
 *   b.如果左子树非空,将左子树入队列
 *   c.如果右子树非空,将右子树入队列
 * 3.执行完成
 */
public List<List<Integer>> levelOrder(TreeNode root) {

    List<List<Integer>> lists = new ArrayList<>();

    if (root == null) {
        return lists;
    }

    Queue<LevelNode> queue = new ArrayDeque<>();
    queue.add(new LevelNode(root,0));
    while (!queue.isEmpty()) {

        LevelNode levelNode = queue.poll();
        List<Integer> nodeList = null;
        if (levelNode.level == lists.size()) {
           nodeList = new ArrayList<>();
            lists.add(nodeList);
        }else {
            nodeList = lists.get(levelNode.level);
        }
        nodeList.add(levelNode.node.val);
        if (levelNode.node.left != null) {
            queue.add(new LevelNode(levelNode.node.left,levelNode.level+1));
        }

        if (levelNode.node.right != null) {
            queue.add(new LevelNode(levelNode.node.right,levelNode.level+1));
        }
    }
    return lists;
}

public List preorderTraversal1(TreeNode root) {

    List<Integer> res = new ArrayList<>();
    if (root != null) {

        res.add(root.val);
        preorderTraversal1(root.left);
        preorderTraversal1(root.right);
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值