剑指Offer-二叉树相关

Created at 2018-09-11 Updated at 2020-07-29 Category 算法 Tag 剑指Offer

7. 重建二叉树

leetcode 105

public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
    if (pre == null || in == null) {
        return null;
    }
    return func(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
public TreeNode func(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
    if (startPre > endPre || startIn > endIn)
        return null;
    TreeNode node = new TreeNode(pre[startPre]);
    for (int i = startIn; i <= endIn; i++) {
        if (in[i] == pre[startPre]) {
            node.left = func(pre, startPre + 1, i - startIn + startPre, in, startIn, i - 1);
            node.right = func(pre, i - startIn + startPre + 1, endPre, in, i + 1, endIn);
            break;
        }
    }
    return node;
}

8. 二叉树的下一个结点

牛客

public TreeLinkNode GetNext(TreeLinkNode pNode) {
    if (pNode == null) {
        return null;
    }
    if (pNode.right != null) {
        pNode = pNode.right;
        while (pNode.left != null) {
            pNode = pNode.left;
        }
        return pNode;
    }
    while (pNode.next != null && pNode.next.left != pNode) {
        pNode = pNode.next;
    }
    return pNode.next;
}

26. 树的子结构

leetcode 572

public boolean isSubtree(TreeNode s, TreeNode t) {
    if (s == null || t == null) {
        return false;
    }
    return helper(s, t) || isSubtree(s.left, t) || isSubtree(s.right, t);
}
public boolean helper(TreeNode s, TreeNode t) {
    if (t == null && s == null) {
        return true;
    }
    if (t == null || s == null) {
        return false;
    }
    if (s.val != t.val) {
        return false;
    }
    return helper(s.left, t.left) && helper(s.right, t.right);
}

27. 二叉树的镜像

leetcode 226

public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return null;
    }
    if (root.left != null) {
        invertTree(root.left);
    }
    if (root.right != null) {
        invertTree(root.right);
    }
    TreeNode node = root.left;
    root.left = root.right;
    root.right = node;
    return root;
}

28. 对称的二叉树

leetcode 101

public boolean isSymmetric(TreeNode root) {
    if (root == null) {
        return true;
    }
    return helper(root.left, root.right);
}
public boolean helper(TreeNode l, TreeNode r) {
    if (r == null) {
        return l == r;
    }
    if (l == null) {
        return false;
    }
    if (l.val != r.val) {
        return false;
    }
    return helper(l.left, r.right) && helper(l.right, r.left);
}

32.1 从上往下打印二叉树

public List<Integer> PrintFromTopToBottom(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    Deque<TreeNode> nodes = new LinkedList<>();
    nodes.add(root);
    while (!nodes.isEmpty()) {
        TreeNode node = nodes.pop();
        res.add(node.val);
        if (node.left != null) {
            nodes.add(node.left);
        }
        if (node.right != null) {
            nodes.add(node.right);
        }
    }
    return res;
}

32.2 分行从上到下打印二叉树

leetcode 102

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    LinkedList<TreeNode> nodes = new LinkedList<>();
    nodes.add(root);
    while (!nodes.isEmpty()) {
        int size = nodes.size();
        List<Integer> line = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            TreeNode node = nodes.pop();
            line.add(node.val);
            if (node.left != null) {
                nodes.add(node.left);
            }
            if (node.right != null) {
                nodes.add(node.right);
            }
        }
        res.add(line);
    }
    return res;
}

32.3 之字形打印二叉树

leetcode 103

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> ret = new LinkedList<>();
    if (root == null)
        return ret;
    LinkedList<TreeNode> queue = new LinkedList<>();
    queue.push(root);
    boolean startLeft = true;
    while (!queue.isEmpty()) {
        int size = queue.size();
        List<Integer> level = new LinkedList<>();
        for (int i = 0; i < size; i++) {
            TreeNode n = queue.removeLast();
            if (n.left != null)
                queue.push(n.left);
            if (n.right != null)
                queue.push(n.right);
            if (startLeft)
                level.add(n.val);
            else
                level.add(0, n.val);
        }
        ret.add(level);
        startLeft = !startLeft;
    }
    return ret;
}

33. 二叉搜索树的后序遍历序列

public boolean VerifySquenceOfBST(int[] sequence) {
    if (sequence == null || sequence.length == 0) {
        return false;
    }
    if (sequence.length == 1) {
        return true;
    }
    return Verify(sequence, 0, sequence.length - 1);
}
public boolean Verify(int[] sequence, int l, int r) {
    if (l >= r) {
        return true;
    }
    int i = l;
    while (sequence[i] < sequence[r]) {
        i++;
    }
    for (int j = i; j < r; j++) {
        if (sequence[j] < sequence[r]) {
            return false;
        }
    }
    return Verify(sequence, l, i - 1) && Verify(sequence, i, r - 1);
}

34. 二叉树中和为某一值的路径

leetcode 113

List<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
    helper(root, sum);
    return res;
}
public void helper(TreeNode root, int sum) {
    if (root == null) {
        return;
    }
    sum -= root.val;
    path.add(root.val);
    if (sum == 0 && root.left == null && root.right == null) {
        res.add(new LinkedList<>(path));
    } else {
        helper(root.left, sum);
        helper(root.right, sum);
    }
    path.removeLast();
}

相关题目:leetcode 437

36. 二叉搜索树与双向链表

public TreeNode last = null;
public TreeNode Convert(TreeNode pRootOfTree) {
    if (pRootOfTree == null) {
        return null;
    }
    helper(pRootOfTree);
    while (last != null && last.left != null) {
        last = last.left;
    }
    return last;
}
public void helper(TreeNode root) {
    if (root == null) {
        return;
    }
    helper(root.left);
    root.left = last;
    if (last != null) {
        last.right = root;
    }
    last = root;
    helper(root.right);
}

相关题目:

37. 序列化二叉树

leetcode 297

public String serialize(TreeNode root) {
    StringBuilder res = strHelp(root, new StringBuilder());
    return res.toString();
}
public StringBuilder strHelp(TreeNode root, StringBuilder str) {
    if (root == null) {
        str.append("#,");
        return str;
    }
    str.append(root.val);
    str.append(",");
    strHelp(root.left, str);
    strHelp(root.right, str);
    return str;
}
public TreeNode deserialize(String data) {
    String[] strWord = data.split(",");
    Deque<String> listWord = new LinkedList<>(Arrays.asList(strWord));
    return deserHelp(listWord);
}
public TreeNode deserHelp(Deque<String> deque) {
    if (deque.peek().equals("#")) {
        deque.pop();
        return null;
    }
    TreeNode res = new TreeNode(Integer.valueOf(deque.pop()));
    res.left = deserHelp(deque);
    res.right = deserHelp(deque);
    return res;
}

相关题目:

54. 二叉搜索树的第K大节点

leetcode 230

int res, cnt;
public int kthSmallest(TreeNode root, int k) {
    cnt = k;
    helper(root);
    return res;
}
public void helper(TreeNode root) {
    if (root == null) {
        return;
    }
    helper(root.left);
    cnt--;
    if (cnt == 0) {
        res = root.val;
        return;
    }
    helper(root.right);
}

55.1 二叉树的深度

leetcode 104

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int left = maxDepth(root.left);
    int right = maxDepth(root.right);
    return left > right ? left + 1 : right + 1;
}

55.2 平衡二叉树

leetcode 110

boolean res = true;
public boolean isBalanced(TreeNode root) {
    helper(root);
    return res;
}
public int helper(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int left = helper(root.left);
    int right = helper(root.right);
    int diff = left - right;
    if (diff > 1 || diff < -1) {
        res = false;
    }
    return left > right ? left + 1 : right + 1;
}

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

leetocde 235

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if (root == null || p == root || q == root) {
        return root;
    }
    while (root != null) {
        if (root.val > p.val && root.val > q.val) {
            root = root.left;
        } else if (root.val < p.val && root.val < q.val) {
            root = root.right;
        } else {
            return root;
        }
    }
    return null;
}

69.2 二叉树的最近公共祖先

leetcode 236

递归

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

求出根节点到指定节点的路径再求出路径的相交点

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if (root == null) {
        return null;
    }
    if (root == p || root == q || (root.left == p && root.right == q)) {
        return root;
    }
    LinkedList<TreeNode> pathP = new LinkedList<>();
    LinkedList<TreeNode> pathQ = new LinkedList<>();
    getPath(root, p, pathP);
    getPath(root, q, pathQ);
    TreeNode last = null;
    for (int i = 0; i < pathP.size() && i < pathQ.size(); i++) {
        if (pathP.get(i) == pathQ.get(i)) {
            last = pathP.get(i);
        } else {
            break;
        }
    }
    return last;
}
public boolean getPath(TreeNode root, TreeNode p, LinkedList<TreeNode> path) {
    if (root == null) {
        return false;
    }
    path.add(root);
    if (root == p || getPath(root.left, p, path) || getPath(root.right, p, path)) {
        return true;
    }
    path.removeLast();
    return false;
}
Site by Cellophane using Hexo & Random

Hide