第11节.pptx

二叉树一些题目

题目1:按层遍历二叉树

其实就是宽度优先遍历,用队列

  1. public static void levelTravesalBT(TreeNode root) {
  2. if (root == null) {
  3. return;
  4. }
  5. Queue<TreeNode> queue = new LinkedList<>();
  6. queue.offer(root);
  7. while (!queue.isEmpty()) {
  8. TreeNode node = queue.poll();
  9. if (node.left != null) {
  10. queue.offer(node.left);
  11. }
  12. if (node.right != null) {
  13. queue.offer(node.right);
  14. }
  15. System.out.print(node.value + " ");
  16. }
  17. }

题目2:实现二叉树的序列化和反序列化

  1. /*
  2. * 通过先序遍历序列化
  3. * */
  4. public static Queue<String> preSerialize(TreeNode root) {
  5. Queue<String> queue = new LinkedList<>();
  6. pres(root, queue);
  7. return queue;
  8. }
  9. private static void pres(TreeNode treeNode, Queue<String> queue) {
  10. if (treeNode == null) {
  11. queue.offer(null);
  12. } else {
  13. queue.add(String.valueOf(treeNode.value));
  14. pres(treeNode.left, queue);
  15. pres(treeNode.right, queue);
  16. }
  17. }
  18. public static TreeNode buildByPreSerialize(Queue<String> queue) {
  19. if (queue == null || queue.size() == 0) {
  20. return null;
  21. }
  22. return preBuild(queue);
  23. }
  24. private static TreeNode preBuild(Queue<String> queue) {
  25. String val = queue.poll();
  26. if (val == null) {
  27. return null;
  28. }
  29. TreeNode root = new TreeNode(Integer.parseInt(val));
  30. root.left = preBuild(queue);
  31. root.right = preBuild(queue);
  32. return root;
  33. }
  34. // for test
  35. public static TreeNode generateRandomBST(int maxLevel, int maxValue) {
  36. return generate(1, maxLevel, maxValue);
  37. }
  38. // for test
  39. public static TreeNode generate(int level, int maxLevel, int maxValue) {
  40. if (level > maxLevel || Math.random() < 0.5) {
  41. return null;
  42. }
  43. TreeNode root = new TreeNode((int) (Math.random() * maxValue));
  44. root.left = generate(level + 1, maxLevel, maxValue);
  45. root.right = generate(level + 1, maxLevel, maxValue);
  46. return root;
  47. }
  48. public static boolean isSameValueStructure(TreeNode root1, TreeNode root2) {
  49. if (root1 == null && root2 == null) {
  50. return true;
  51. }
  52. if (root1 != null ^ root2 != null) {
  53. return false;
  54. }
  55. if (root1.value != root2.value) {
  56. return false;
  57. }
  58. return isSameValueStructure(root1.left, root2.left) && isSameValueStructure(root1.right, root2.right);
  59. }
  60. // for test
  61. public static void printTree(TreeNode root) {
  62. System.out.println("Binary Tree:");
  63. printInOrder(root, 0, "H", 17);
  64. System.out.println();
  65. }
  66. public static void printInOrder(TreeNode root, int height, String to, int len) {
  67. if (root == null) {
  68. return;
  69. }
  70. printInOrder(root.right, height + 1, "v", len);
  71. String val = to + root.value + to;
  72. int lenM = val.length();
  73. int lenL = (len - lenM) / 2;
  74. int lenR = len - lenM - lenL;
  75. val = getSpace(lenL) + val + getSpace(lenR);
  76. System.out.println(getSpace(height * len) + val);
  77. printInOrder(root.left, height + 1, "^", len);
  78. }
  79. public static String getSpace(int num) {
  80. String space = " ";
  81. StringBuffer buf = new StringBuffer("");
  82. for (int i = 0; i < num; i++) {
  83. buf.append(space);
  84. }
  85. return buf.toString();
  86. }
/*
 * 通过后序遍历序列化
 * */

public static Queue<String> posSerialize(TreeNode root) {
    Queue<String> queue = new LinkedList<>();
    poss(root, queue);
    return queue;
}

private static void poss(TreeNode treeNode, Queue<String> queue) {
    if (treeNode == null) {
        queue.offer(null);
    } else {
        poss(treeNode.left, queue);
        poss(treeNode.right, queue);
        queue.offer(String.valueOf(treeNode.value));
    }
}

public static TreeNode buildByPosSerialize(Queue<String> queue) {
    if (queue == null || queue.size() == 0) {
        return null;
    }
    Stack<String> stack = new Stack<>();
    while (!queue.isEmpty()) {
        stack.push(queue.poll());
    }
    return posBuild(stack);
}

private static TreeNode posBuild(Stack<String> stack) {
    String val = stack.pop();
    if (val == null) {
        return null;
    }
    TreeNode root = new TreeNode(Integer.parseInt(val));
    root.right = posBuild(stack);
    root.left = posBuild(stack);
    return root;
}
/*
 * 通过按层遍历序列化
 * */

public static Queue<String> levelSerialize(TreeNode root) {
    Queue<String> queue = new LinkedList<>();

    Queue<TreeNode> help = new LinkedList<>();
    if (root == null) {
        queue.offer(null);
    } else {
        queue.offer(String.valueOf(root.value));
        help.offer(root);
        while (!help.isEmpty()) {
            TreeNode cur = help.poll();
            if (cur.left == null) {
                queue.offer(null);
            } else {
                queue.offer(String.valueOf(cur.left.value));
                help.offer(cur.left);
            }
            if (cur.right == null) {
                queue.offer(null);
            } else {
                queue.offer(String.valueOf(cur.right.value));
                help.offer(cur.right);
            }
        }
    }
    return queue;
}

public static TreeNode buildByLevelSerialize(Queue<String> queue) {
    if (queue == null || queue.size() == 0) {
        return null;
    }

    String val = queue.poll();
    TreeNode root = generateTreeNode(val);
    Queue<TreeNode> help = new LinkedList<>();
    if (root != null) {
        help.offer(root);
    }

    while (!help.isEmpty()) {
        TreeNode cur = help.poll();
        cur.left = generateTreeNode(queue.poll());
        cur.right = generateTreeNode(queue.poll());
        if (cur.left != null) {
            help.offer(cur.left);
        }
        if (cur.right != null) {
            help.offer(cur.right);
        }
    }
    return root;
}

private static TreeNode generateTreeNode(String s) {
    if (s == null) {
        return null;
    } else {
        return new TreeNode(Integer.parseInt(s));
    }
}

题目3:Encode N-ary Tree to Binary Tree

一个多叉树,编码转换为颗二叉树,解码二叉树转换为一颗多叉树。


public class Node {

    protected int val;
    protected List<Node> children;

    protected Node() {
    }

    public Node(int val) {
        this.val = val;
    }

    public Node(int val, List<Node> children) {
        this.val = val;
        this.children = children;
    }
}

public class TreeNode {
    protected int val;
    protected TreeNode left;
    protected TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}


public TreeNode encode(Node root) {
    if (root == null) {
        return null;
    }
    TreeNode head = new TreeNode(root.val);
    head.left = encode(root.children);
    return head;
}

private TreeNode encode(List<Node> children) {
    TreeNode head = null;
    TreeNode cur = null;
    for (Node child : children) {
        TreeNode treeNode = new TreeNode(child.val);
        if (head == null) {
            head = treeNode;
        } else {
            cur.right = treeNode;
        }
        cur = treeNode;
        cur.left = encode(child.children);
    }
    return head;
}


public Node decode(TreeNode root) {
    if (root == null) {
        return null;
    }
    return new Node(root.val, de(root.left));
}

private List<Node> de(TreeNode root) {
    List<Node> children = new ArrayList<>();
    while (root != null) {
        Node cur = new Node(root.val, de(root.left));
        children.add(cur);
        root = root.right;
    }
    return children;
}

题目4:打印一颗二叉树

public static void printTree(TreeNode head) {
    System.out.println("Binary Tree:");
    printInOrder(head, 0, "H", 17);
    System.out.println();
}

private static void printInOrder(TreeNode head, int height, String to, int len) {
    if (head == null) {
        return;
    }
    printInOrder(head.right, height + 1, "v", len);

    String val = to + head.val + to;
    int lenM = val.length();
    int lenL = (len - lenM) / 2;
    int lenR = len - lenM - lenL;
    val = getSpace(lenL) + val + getSpace(lenR);
    System.out.println(getSpace(height * len) + val);

    printInOrder(head.left, height + 1, "^", len);
}

private static String getSpace(int num) {
    String space = " ";
    StringBuffer buf = new StringBuffer("");
    for (int i = 0; i < num; i++) {
        buf.append(space);
    }
    return buf.toString();
}

题目5:求二叉树最宽的层有多少个节点

public static int maxWidth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    TreeNode curLevelEndNode = root;
    TreeNode nextLevelEndNode = null;
    int curLevelNodeNum = 0;
    int max = 0;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        TreeNode cur = queue.poll();
        if (cur.left != null) {
            queue.offer(cur.left);
            nextLevelEndNode = cur.left;
        }
        if (cur.right != null) {
            queue.offer(cur.right);
            nextLevelEndNode = cur.right;
        }
        curLevelNodeNum++;
        if (cur == curLevelEndNode) {
            max = Math.max(max, curLevelNodeNum);
            curLevelEndNode = nextLevelEndNode;
            curLevelNodeNum = 0;
        }
    }
    return max;
}
public static int maxWidthUseMap(TreeNode root) {
    if (root == null) {
        return 0;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    HashMap<TreeNode, Integer> levelMap = new HashMap<>(16);
    levelMap.put(root, 1);
    int curLevel = 1;
    int curLevelNodes = 0;
    int max = 0;
    while (!queue.isEmpty()) {
        TreeNode cur = queue.poll();
        int curNodeLevel = levelMap.get(cur);
        if (cur.left != null) {
            queue.offer(cur.left);
            levelMap.put(cur.left, curNodeLevel + 1);
        }
        if (cur.right != null) {
            queue.offer(cur.right);
            levelMap.put(cur.right, curNodeLevel + 1);
        }
        if (curNodeLevel == curLevel) {
            curLevelNodes++;
        } else {
            max = Math.max(max, curLevelNodes);
            curLevel++;
            curLevelNodes = 1;
        }
    }
    max = Math.max(max, curLevelNodes);
    return max;
}

题目6 后继节点

题目:给你二叉树中的某个节点,返回该节点的后继节点 。
后继节点:一棵二叉树,在中序遍历中,一个结点的下一个结点!


static class Node {
    int value;
    Node left;
    Node right;
    Node parent;

    public Node(int value) {
        this.value = value;
    }
}

// 给你二叉树中的某个节点,返回该节点的后继节点


public static Node getSuccessorNode(Node node) {
    if (node == null) {
        return null;
    }
    if (node.right != null) {
        return getLeftMost(node.right);
    } else {
        Node parent = node.parent;
        while (parent != null && parent.right == node) {
            node = parent;
            parent = node.parent;
        }
        return parent;
    }
}

private static Node getLeftMost(Node node) {
    if (node == null) {
        return null;
    }
    while (node.left != null) {
        node = node.left;
    }
    return node;
}

题目7 折纸打印折痕

请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。 如果从纸条的下边向上方连续对折2次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。
给定一个输入参数N,代表纸条都从下边向上方连续对折N次。 请从上到下打印所有折痕的方向。
例如:N=1时,打印: down N=2时,打印: down down up

类似二叉树中序遍历,折痕二叉树,每个左节点为凹,右节点为凸。二叉树层数为折的次数。

public static void printAllFolds(int n) {
    process(1, n, true);
}

private static void process(int i, int n, boolean down) {
    if (i > n) {
        return;
    }
    process(i + 1, n, true);
    System.out.print(down ? "凹 " : "凸 ");
    process(i + 1, n, false);
}