渣渣的leetcode刷題筆記-樹(1)

這兩天在作tree的題目(easy),基本上每道都實現了**recursive**和**iterative**兩種解法,簡單整理一下。

感想:node

  1. 能用BFS+queue解決的基本均可以用DFS+stack解決,尤爲是用preorder,由於它有一種寫法和層序遍歷十分相近。
  2. 遍歷兩棵樹的問題(有時是同一棵樹的左右子樹)最重要的就是要解決同步的問題。
  • 100. Same Tree
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

Recursive Solutionapp

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

BFS Solution:用一個queueide

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) return true;
        if (p == null || q == null) return false;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(p);
        queue.offer(q);
        while(!queue.isEmpty()){
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
            if(node1 == null && node2 == null)  continue;
            if(node1 == null || node2 == null || node1.val != node2.val)    return false;
            queue.offer(node1.left);
            queue.offer(node2.left);
            queue.offer(node1.right);
            queue.offer(node2.right);
        }
        return true;
    }
}

DFS Solution: 用兩個stack和BFS一樣的思路來實現(代碼是preorder的,可是順序不重要,核心是遍歷)this

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(p);
        stack2.push(q);
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            TreeNode node1 = stack1.pop();
            TreeNode node2 = stack2.pop();
            if (node1 == null && node2 == null) continue;
            if (node1 == null || node2 == null) return false;
            if (node1.val != node2.val) return false;
            stack1.push(node1.right);
            stack2.push(node2.right);
            stack1.push(node1.left);
            stack2.push(node2.left);
        }
        return true;
    }
}
  • 101. Symmetric Tree
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

分析:這題是第100題的變體,能夠當作判斷一棵樹的左右子樹是不是鏡像對稱,且若是A,B兩棵樹是鏡像堆成的,那麼A樹的左子樹和B樹的右子樹鏡像對稱,A樹的右子樹和B樹的左子樹鏡像堆成,且根節點相等。code

Recursive Solutionip

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

BFS+queue Solutionget

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null || root.left == null && root.right == null)    return true;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);
        while (!queue.isEmpty()) {
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
            if (node1 == null && node2 == null) continue;
            if (node1 == null || node2 == null) return false;
            if (node1.val != node2.val) return false;
            queue.offer(node1.left);
            queue.offer(node2.right);
            queue.offer(node1.right);
            queue.offer(node2.left);
        }
        return true;
    }
}

DFS+stack solution同步

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null)   return true;
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(root.left);
        stack2.push(root.right);
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            TreeNode node1 = stack1.pop();
            TreeNode node2 = stack2.pop();
            if (node1 == null && node2 == null) continue;
            if (node1== null || node2 == null)  return false;
            if (node1.val != node2.val) return false;
            stack1.push(node1.right);
            stack2.push(node2.left);
            stack1.push(node1.left);
            stack2.push(node2.right);
        }
        return true;
    }
}
  • 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).

Recursive Solution(真的想不出)it

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> wrapList = new LinkedList<List<Integer>>();
//        if (root == null)   return wrapList;
        levelOrderMaker(wrapList, root, 0);
        return wrapList;
    }
    
    public void levelOrderMaker(List<List<Integer>> wrapList, TreeNode root, int level) {
        if (root == null)   return;
        if (level == wrapList.size())
            wrapList.add(new LinkedList<Integer>());
        wrapList.get(level).add(root.val);
        levelOrderMaker(wrapList, root.left, level + 1);
        levelOrderMaker(wrapList, root.right, level + 1);
    }
}

BFS Solutionio

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> wrapList= new LinkedList<>();
        if (root == null)   return wrapList;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> subList = new LinkedList<>();
            int size = queue.size();
            for (int i = 0; i < size; i ++) {
                TreeNode node = queue.poll();
                subList.add(node.val);
                if (node.left != null)  queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
            wrapList.add(subList);
        }
        return wrapList;
    }
}

BFS的這種寫法和常規寫法的不一樣之處在於,每次循環都遍歷了這一層的全部節點。所以這種解法也能夠用來求tree的最大深度最小深度,在此就不整理了。
另外107題和102幾乎相同,只要將BFS Solution中wrapList.add(subList)改成wraplist.add(0, subList)便可。Recursive Solution中將

if (level == wrapList.size())
            wrapList.add(new LinkedList<Integer>());
        wrapList.get(level).add(root.val);

改成

if (level == wrapList.size())
            wrapList.add(0, new LinkedList<Integer>()); 
        wrapList.get(wrapList.size()-level-1).add(root.val);
  1. 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.

mutipass: 很是直觀的解法,從平衡樹的定義入手:左右子樹均爲平衡樹且子樹的高度差不超過1

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null)   return true;
        if (Math.abs(height(root.left) - height(root.right)) <= 1 &&
           isBalanced(root.left) && isBalanced(root.right)) return true;
        return false;
    }
    private int height(TreeNode root) {
        if (root == null)   return 0;
        return Math.max(height(root.left), height(root.right)) + 1;
    }
}

可是這種解法會存在大量的重複計算,因而就有了第二種解法,時間複雜度爲O(n)。
onepass(真的想不出)

class Solution {
    public boolean isBalanced(TreeNode root) {
        return balanceHeight(root) != -1;
    }
    
    private int balanceHeight(TreeNode root) {
        if (root == null)   return 0;
        int lHeight = balanceHeight(root.left);
        if (lHeight == -1)  return -1;
        int rHeight = balanceHeight(root.right);
        if (rHeight == -1)  return -1;
        if (Math.abs(lHeight-rHeight) > 1) return -1;
        return Math.max(lHeight, rHeight) + 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.

分析:hasPathSum(root.left, sum-root.val)或hasPathSum(root.right, sum-root.val)成當即可

Recursive Solution(意外得好寫):

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null)   return false;
        if (root.left == null && root.right == null && root.val == sum) return true;
        if (hasPathSum(root.left, sum-root.val) == true ||hasPathSum(root.right, sum-root.val) == true) return true;
        return false;
    }
}

BFS+queue:(每一個葉子節點到根節點的路徑是惟一的,因此能夠在遍歷過程當中將每一個節點到根的路徑上的節點和存起來,固然用stack也是徹底能夠的)

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null)   return false;
        Queue<TreeNode> Q1 = new LinkedList<TreeNode>();
        Queue<Integer>  Q2 = new LinkedList<Integer>();
        Q1.offer(root);
        Q2.offer(root.val);
        while(!Q1.isEmpty()) {
            int size = Q1.size();
            for (int i = 0; i < size; i ++) {
                TreeNode node = Q1.poll();
                int val = Q2.poll();
                if (val == sum && node.left == null && node.right == null) return true;
                if (node.left != null) {
                    Q1.offer(node.left);
                    Q2.offer(val + node.left.val);
                }
                if (node.right != null) {
                    Q1.offer(node.right);
                    Q2.offer(val + node.right.val);
                }
            }
        }
        return false;
    }
}
  • 226. Invert Binary Tree
Invert a binary tree.

recursive solution:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null)   return null;
        TreeNode tmp = root.left;
        root.left = invertTree(root.right);
        root.right = invertTree(tmp);
        return root;
    }
}

BFS Solution(在遍歷過程當中交換左右節點,用stack+preorder也是同樣的道理,不放代碼了)

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null)   return null;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            TreeNode tmp = node.left;
            node.left = node.right;
            node.right = tmp;
            if (node.left != null)  queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        return root;
    }
}
  • 617. Merge Two Binary Trees
Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.
You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree

Recursive solution

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

BFS Solution (很好地解決了同步遍歷兩棵樹的問題)

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if (t1 == null) return t2;
        if (t2 == null) return t1;
        Queue<TreeNode> queue1 = new LinkedList<>();
        Queue<TreeNode> queue2 = new LinkedList<>();
        queue1.offer(t1);
        queue2.offer(t2);
        while (!queue1.isEmpty()) {
            TreeNode node1 = queue1.poll();
            TreeNode node2 = queue2.poll();
            node1.val += node2.val;
            if (node1.left == null && node2.left != null)
                node1.left = node2.left;
            else if (node1.left != null && node2.left != null) {
                queue1.add(node1.left);
                queue2.add(node2.left);
            }
            if (node1.right == null && node2.right != null)
                node1.right = node2.right;
            else if (node1.right != null && node2.right != null) {
                queue1.add(node1.right);
                queue2.add(node2.right);
            }
        }
        return t1;
    }
}
相關文章
相關標籤/搜索