LeetCode专题----Tree

94. Binary Tree Inorder Traversal

Given a binary tree, return the inorder traversal of its nodes’ values.
解法1:递归。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;

        inOrder(root, ret);
        return ret;
    }

    private void inOrder(TreeNode root, List<Integer> ret) {
        if(root.left != null) inOrder(root.left, ret);
        ret.add(root.val);
        if(root.right != null) inOrder(root.right, ret);
    }
}

解法2:循环。这个和前序后序不太一样。先从跟节点一路把左节点压入栈,再在弹出每个元素的时候对其右节点进行同样的处理。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;

        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        // 终止条件,不光是栈为空,栈空的时候栈最后一个元素的右节点还没处理,只有在栈空且栈的最后一个弹出元素没有右节点时才终止
        while(cur != null || !stack.empty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            ret.add(cur.val);
            cur = cur.right;
        }
        return ret;
    }
}

144. Binary Tree Preorder Traversal

Given a binary tree, return the preorder traversal of its nodes’ values.
解法1:递归

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;
        preOrder(root, ret);
        return ret;
    }
    private void preOrder(TreeNode root, List<Integer> ret) {
        ret.add(root.val);
        if(root.left != null) preOrder(root.left, ret);
        if(root.right != null) preOrder(root.right, ret);
    }
}

解法2:循环。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;

        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode cur = stack.pop();
            ret.add(cur.val);
            if(cur.right != null) {
                stack.push(cur.right);
            }
            if(cur.left != null) {
                stack.push(cur.left);
            }
        }
        return ret;
    }
}

145. Binary Tree Postorder Traversal

Given a binary tree, return the postorder traversal of its nodes’ values.
解答1:递归

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;
        postOrder(root, ret);
        return ret;
    }

    private void postOrder(TreeNode root, List<Integer> ret) {
        if(root.left != null) postOrder(root.left, ret);
        if(root.right != null) postOrder(root.right, ret);
        ret.add(root.val);
    }
}

解答2:循环。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();

        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root, pre = null;
        while(stack.peek() != null || cur != null) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.peek();
            // 如果右子树为空或者已经处理过了才处理当前节点,注意清空cur
            if(cur.right == null || cur.right == pre) {
                ret.add(cur.val);
                stack.pop();
                pre = cur;
                cur = null;
            }
            else {
                cur = cur.right;
            }
        }
        return ret;
    }
}

102. Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
解法1:循环。用到ArrayList和Queue。确定每个level的大小。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<List<Integer>>();
        if(root == null) return ret;

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> subList = new ArrayList<>();
            for(int i=0;i<levelSize;i++) {
                TreeNode cur = queue.poll();
                subList.add(cur.val);
                if(cur.left != null) queue.offer(cur.left);
                if(cur.right != null) queue.offer(cur.right);
            }
            ret.add(subList);
        }
        return ret;
    }
}

解法2:递归。需要一个depth变量来标记当前节点的深度,以便把该节点加入到对应的list中去。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    List<List<Integer>> result = new ArrayList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        addToLevelList(root, 0);
        return result;
    }

    public void addToLevelList(TreeNode root, int depth) {
        if(root == null) {
            return;
        }

        if(result.size() < depth+1)
            result.add(depth, new ArrayList<Integer>());

        result.get(depth).add(root.val);

        depth ++;
        if(root.left != null)
            addToLevelList(root.left, depth);
        if(root.right != null)
            addToLevelList(root.right, depth);
    }
}

107. Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).
思路:循环的方法和上题类似,只要把外层ArrayList换成LinkedList,然后每个subList都addFirst。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        LinkedList<List<Integer>> ret = new LinkedList<List<Integer>>();
        if(root == null) return ret;

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> subList = new ArrayList<>();
            for(int i=0;i<levelSize;i++) {
                TreeNode cur = queue.remove();
                subList.add(cur.val);
                if(cur.left != null) queue.offer(cur.left);
                if(cur.right != null) queue.offer(cur.right);
            }
            ret.addFirst(subList);
        }
        return ret;
    }
}

103. Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
思路:和上面两题类似,只需要把内层list改为LinkedList,然后设置一个交替变化的标志来表明该level是正向还是反向,进而决定是addLast还是addFirst。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null) return ret;

        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        Boolean order = true;
        while(!queue.isEmpty()) {
            int levelSize = queue.size();
            LinkedList<Integer> subList = new LinkedList<>();
            for(int i=0;i<levelSize;i++) {
                TreeNode cur = queue.poll();

                if(order) subList.addLast(cur.val);
                else subList.addFirst(cur.val);

                if(cur.left != null) queue.add(cur.left);
                if(cur.right != null) queue.add(cur.right);
            }
            ret.add(subList);
            order = !order;
        }
        return ret;
    }
}

99. Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
思路:中序遍历的顺序就是从小到大的顺序,记录前一个节点,如果前一个节点大于当前节点的值,那么就找到了一个打乱的元素。第一次找到的元素应该是前一个节点,第二次找到的元素是当前节点。

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

    TreeNode first = null;
    TreeNode second = null;
    TreeNode preNode = new TreeNode(Integer.MIN_VALUE);

    public void recoverTree(TreeNode root) {
        if(root == null) return;
        if(root.left == null && root.right == null) return;

        helper(root);

        int tmp = first.val;
        first.val = second.val;
        second.val = tmp;
    }

    public void helper(TreeNode root) {
        if(root.left != null) {
            helper(root.left);
        }
        if(root.val < preNode.val) {
            if(first == null)
                first = preNode;
            if(first != null)
                second = root;
        }
        preNode = root;
        if(root.right != null) {
            helper(root.right);
        }
    }
}

100. Same Tree

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.
思路:递归,想清楚终止条件,分四种情况。都是null,一个是null,值相等,值不等。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {

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

101. Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
思路:递归,和上题有些类似。

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

        return isSymmetricTwo(root.left, root.right);
    }

    public boolean isSymmetricTwo(TreeNode tree1, TreeNode tree2) {
        if(tree1 == null && tree2 == null) return true;
        if(tree1 == null || tree2 == null) return false;

        if(tree1.val != tree2.val) return false;

        return isSymmetricTwo(tree1.left, tree2.right) && isSymmetricTwo(tree1.right, tree2.left);
    }
}

104. Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
解法1:递归。当前节点的深度等于左右子树的最大深度加1。

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

        int left = maxDepth(root.left);
        int right = maxDepth(root.right);

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

解法2:循环,BFS,类似层序遍历。

public int maxDepth(TreeNode root) {
    if(root == null) {
        return 0;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    int count = 0;
    while(!queue.isEmpty()) {
        int size = queue.size();
        while(size-- > 0) {
            TreeNode node = queue.poll();
            if(node.left != null) {
                queue.offer(node.left);
            }
            if(node.right != null) {
                queue.offer(node.right);
            }
        }
        count++;
    }
    return count;
}

解法3:循环,DFS。两个stack,一个存节点,一个存节点对应的深度。

public int maxDepth(TreeNode root) {
    if(root == null) {
        return 0;
    }

    Stack<TreeNode> stack = new Stack<>();
    Stack<Integer> value = new Stack<>();
    stack.push(root);
    value.push(1);
    int max = 0;
    while(!stack.isEmpty()) {
        TreeNode node = stack.pop();
        int temp = value.pop();
        max = Math.max(temp, max);
        if(node.left != null) {
            stack.push(node.left);
            value.push(temp+1);
        }
        if(node.right != null) {
            stack.push(node.right);
            value.push(temp+1);
        }
    }
    return max;
}

111. Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
思路:递归。但是在合并左右子树的最小深度来计算当前节点的最小深度的时候要注意左右子树中有且只有一个深度是0的情况,这种情况下当前节点不是叶子节点,深度要取非零子树的深度加1。

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

        return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1;
    }
}

108. Convert Sorted Array to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
思路:递归。每次把中间值设为根节点的值

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

        return helper(nums, 0, nums.length - 1);
    }

    private TreeNode helper(int[] nums, int start, int end) {
        if(start > end) return null;

        int mid = (start + end) >> 1;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, start, mid - 1);
        root.right = helper(nums, mid + 1, end);

        return root;
    }
}

110. Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
思路:递归。判断左右子树是否平衡,若平衡,返回高度,若不平衡返回-1。若左右均平衡,比较左右高度差,判断是否平衡,若平衡,返回当前节点高度。

 /**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isBalanced(TreeNode root) {
        return height(root) != -1;
    }

    private int height(TreeNode root) {
        if(root == null) return 0;

        int left = height(root.left);
        if(left == -1) return -1;
        int right = height(root.right);
        if(right == -1) return -1;

        if(Math.abs(left-right) > 1) return -1;
        return Math.max(left, right) + 1;
    }
}

112. Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
思路:递归。只有当当前左右节点为null且剩余的数为0时才返回true。

public class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if(root == null) return false;

        if(root.left == null && root.right == null && sum - root.val == 0) return true;

        return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
    }
}

113. Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
思路:用一个subList来存储从根节点到当前节点路径上的所有节点,如果剩余和为0了,就把整个路径上的节点加入结果中,否则就左右递归。一定要注意在最后不要忘记把当前节点从list中删除。还有一个要注意的地方是由于java里都是引用,其实这个程序里分配给subList的内存都是同一块,所以在把subList中的结果加入ret中的时候需要新建一个list。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> ret = new ArrayList<List<Integer>>();
        if(root == null) return ret;

        List<Integer> subList = new LinkedList<Integer>();
        helper(root, sum, subList, ret);

        return ret;
    }
    private void helper(TreeNode root, int curLeft, List<Integer> subList, List<List<Integer>> ret) {
        if(root == null) return;

        subList.add(root.val);

        if(root.left == null && root.right == null && root.val == curLeft) {
            ret.add(new LinkedList<Integer>(subList));
        }
        else {
            helper(root.left, curLeft - root.val, subList, ret);
            helper(root.right, curLeft - root.val, subList, ret);
        }
        subList.remove(subList.size()-1);
    }
}

437. Path Sum III

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
思路:递归。类似Two Sum,用一个hashMap保存目前为止前面所有项的和以及到该和的路径个数,要注意加一个和为0,路径个数为1的情况。记得在当前函数结束的时候hashMap中对应的加上当前节点的和对应的路径个数减1。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int pathSum(TreeNode root, int sum) {
        HashMap<Integer, Integer> preSum = new HashMap<>();
        preSum.put(0, 1);
        return helper(root, 0, sum, preSum);
    }
    private int helper(TreeNode root, int curSum, int sum, HashMap<Integer, Integer> preSum) {
        if(root == null) return 0;

        curSum += root.val;
        int ret = preSum.getOrDefault(curSum - sum, 0);
        preSum.put(curSum, preSum.getOrDefault(curSum, 0) + 1);

        ret += helper(root.left, curSum, sum, preSum) + helper(root.right, curSum, sum, preSum);
        preSum.put(curSum, preSum.get(curSum) - 1);
        return ret;
    }
}

114. Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place.

For example,
Given

     1
    / \
   2   5
  / \   \
 3   4   6

The flattened tree should look like:

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

思路:递归。有点类似后序遍历,先递归处理左右子树,在处理两者和root的连接情况。

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

        TreeNode left = root.left, right = root.right;
        // 清空左子树
        root.left = null;

        flatten(left);
        flatten(right);
        // 展平的左子树接在root.right后面
        root.right = left;
        // 展平的右子树接在展平的左子后面
        TreeNode cur = root;
        while(cur.right != null) cur = cur.right;
        cur.right = right;
    }
}

124. Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
思路:A path from start to end, goes up on the tree for 0 or more steps, then goes down for 0 or more steps. Once it goes down, it can’t go up. Each path has a highest node, which is also the lowest common ancestor of all other nodes on the path. A recursive method maxPathDown(TreeNode node) (1) computes the maximum path sum with highest node as the input node, update maximum if necessary (2) returns the maximum sum of the path that can be extended to input node’s parent.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    int maxValue;
    public int maxPathSum(TreeNode root) {
        maxValue = Integer.MIN_VALUE;
        maxPathDown(root);
        return maxValue;
    }

    private int maxPathDown(TreeNode node) {
        if(node == null) return 0;
        int left = Math.max(0, maxPathDown(node.left));
        int right = Math.max(0, maxPathDown(node.right));
        maxValue = Math.max(maxValue, left + right + node.val);
        return Math.max(left, right) + node.val;
    }
}

173. Binary Search Tree Iterator

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
/**
* Your BSTIterator will be called like this:
* BSTIterator i = new BSTIterator(root);
* while (i.hasNext()) v[f()] = i.next();
*/
思路:类似中序遍历。

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

public class BSTIterator {
    Stack<TreeNode> s = new Stack<>();

    public BSTIterator(TreeNode root) {
        pushAll(root);
    }

    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return !s.isEmpty();
    }

    /** @return the next smallest number */
    public int next() {
        TreeNode node = s.pop();
        pushAll(node.right);
        return node.val;
    }

    private void pushAll(TreeNode root) {
        while(root != null) {
            s.push(root);
            root = root.left;
        }
    }
}

226. Invert Binary Tree

解法1:递归,DFS。

public class Solution {
    public TreeNode invertTree(TreeNode root) {

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

        final TreeNode left = root.left,
                right = root.right;
        root.left = invertTree(right);
        root.right = invertTree(left);
        return root;
    }
}

解法2:循环,DFS。

public class Solution {
    public TreeNode invertTree(TreeNode root) {

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

        final Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);

        while(!stack.isEmpty()) {
            final TreeNode node = stack.pop();
            final TreeNode left = node.left;
            node.left = node.right;
            node.right = left;

            if(node.left != null) {
                stack.push(node.left);
            }
            if(node.right != null) {
                stack.push(node.right);
            }
        }
        return root;
    }
}

解法3:循环,BFS,层序遍历。

public class Solution {
    public TreeNode invertTree(TreeNode root) {

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

        final Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while(!queue.isEmpty()) {
            final TreeNode node = queue.poll();
            final TreeNode left = node.left;
            node.left = node.right;
            node.right = left;

            if(node.left != null) {
                queue.offer(node.left);
            }
            if(node.right != null) {
                queue.offer(node.right);
            }
        }
        return root;
    }
}

230. Kth Smallest Element in a BST

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note:
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.
思路:中序遍历。中序遍历的顺序就是排序的顺序。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    int ret = 0;
    int count = 0;
    public int kthSmallest(TreeNode root, int k) {
        count = k;
        helper(root);
        return ret;       
    }

    private void helper(TreeNode root) {
        // root.left
        if(root.left != null) helper(root.left);
        // root
        count--;
        if(count == 0) {
            ret = root.val;
            return;
        }
        // root.right
        if(root.right != null) helper(root.right);
    }
}

235. Lowest Common Ancestor of a Binary Search Tree

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
思路:递归,由于是二叉搜索树,所以问题比较简单。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(p.val<root.val && q.val<root.val) 
            return lowestCommonAncestor(root.left, p, q);
        else if(p.val>root.val && q.val>root.val)
            return lowestCommonAncestor(root.right, p, q);
        else
            return root;
    }
}

236. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
思路:由于不是搜索树了,所以不能简单通过判断和根节点的大小关系来确定子树中是否包含输入节点了。后序的顺序遍历树,如果当前节点的左子树包含一个节点(返回当前节点,否则返回null),右子树包含另一个节点(返回当前节点,否则返回null),那么当前节点就是LCD,返回当前节点,然后这个节点层层上传,直到最后返回。关键是要处理这个层层上传的逻辑。

public 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 && right != null)   return root;
        return left != null ? left : right;
    }
}

257. Binary Tree Paths

Given a binary tree, return all root-to-leaf paths.
思路:递归。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> answer = new ArrayList<String>();

        if(root != null)
            searchBT(root, "", answer);

        return answer;
    }

    private void searchBT(TreeNode root, String path, List<String> answer) { //path负责记录路径,而add只在碰到树叶时
        if(root.left == null && root.right == null)
            answer.add(path + root.val);

        if(root.right != null)
            searchBT(root.right, path + root.val + "->", answer);//未改变path本来的值,因为后面还可能用到

        if(root.left != null)
            searchBT(root.left, path + root.val + "->", answer); 
    }
}

404. Sum of Left Leaves

Find the sum of all left leaves in a given binary tree.
思路:这题主要学习一下递归,使用递归应该想清楚递归的终止条件,终止时要返回的结果。

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

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

450. Delete Node in a BST

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

Search for a node to remove.
If the node is found, delete the node.
Note: Time complexity should be O(height of tree).
思路:保持两个指针pre和cur,先把要删除的cur节点的左右子树拼接起来,再根据cur和pre值的大小确定拼接后的树是pre的左子树还是右子树。

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

        TreeNode fakeRoot = new TreeNode(Integer.MAX_VALUE);
        fakeRoot.left = root;
        TreeNode pre = fakeRoot, cur = root;
        while(cur != null && cur.val != key) {
            if(key < cur.val) {
                pre = cur;
                cur = cur.left;
            }
            else {
                pre = cur;
                cur = cur.right;
            }
        }
        if(cur == null) return root;

        if(cur.left == null) {
            if(cur.val < pre.val) pre.left = cur.right;
            else pre.right = cur.right;
        }
        else if(cur.right == null) {
            if(cur.val < pre.val) pre.left = cur.left;
            else pre.right = cur.left;
        }
        else {
            TreeNode tmp = cur.right;
            while(tmp.left != null) {
                tmp = tmp.left;
            }
            tmp.left = cur.left;
            if(cur.val < pre.val) pre.left = cur.right;
            else pre.right = cur.right;
        }
        return fakeRoot.left;
    }
}

543. Diameter of Binary Tree

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

Example:
Given a binary tree
1
/ \
2 3
/ \
4 5
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].

Note: The length of path between two nodes is represented by the number of edges between them.
思路:递归,但是使用自底向上的思路,不断求解某个节点左右最大深度。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    int diameter = 0;
    public int diameterOfBinaryTree(TreeNode root) {
        height(root);
        return diameter;
    }

    private int height(TreeNode root) {
        if(root == null) return 0;
        int maxLeft = height(root.left);
        int maxRight = height(root.right);
        if(maxLeft + maxRight > diameter) {
            diameter = maxLeft + maxRight;
        }
        return Math.max(maxLeft, maxRight) + 1;
    }
}

310. Minimum Height Trees

For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.

Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
思路:从简单的情况考虑,如果只是一个path graph,那么就是找中点。The actual implementation is similar to the BFS topological sort. Remove the leaves, update the degrees of inner vertexes. Then remove the new leaves. Doing so level by level until there are 2 or 1 nodes left. What’s left is our answer!

class Solution {
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        if (n == 1) return Collections.singletonList(0);

        List<Set<Integer>> adj = new ArrayList<>(n);
        for (int i = 0; i < n; ++i) adj.add(new HashSet<>());
        for (int[] edge : edges) {
            adj.get(edge[0]).add(edge[1]);
            adj.get(edge[1]).add(edge[0]);
        }

        List<Integer> leaves = new ArrayList<>();
        for (int i = 0; i < n; ++i)
            if (adj.get(i).size() == 1) leaves.add(i);

        while (n > 2) {
            n -= leaves.size();
            List<Integer> newLeaves = new ArrayList<>();
            for (int i : leaves) {
                int j = adj.get(i).iterator().next();
                adj.get(j).remove(i);
                if (adj.get(j).size() == 1) newLeaves.add(j);
            }
            leaves = newLeaves;
        }
        return leaves;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值