求根节点到叶节点的数字之和
/**
* 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;
}