[左神面试指南] 二叉树[下]篇

CD172 判断二叉树是否为平衡二叉树

/* 递归 */
public class CD172_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static boolean solution(TreeNode root)
    {
        // {1/0, height}
        return judge(root)[0] == 1;
    }

    public static int[] judge(TreeNode root)
    {
        if (root == null) return new int[]{1, 0};
        if (root.left == null && root.right == null) return new int[]{1, 1};
        int[] leftHeight = judge(root.left);
        int[] rightHeight = judge(root.right);
        return new int[]{(Math.abs(leftHeight[1] - rightHeight[1]) > 1 ? 0 : 1) & leftHeight[0] & rightHeight[0], 1 + Math.max(leftHeight[1], rightHeight[1])};
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode));
    }
}

CD173 根据后序数组重建搜索二叉树

/* 递归 */
public class CD173_1
{

    public static boolean solution(int[] arr)
    {
        return judge(arr, 0, arr.length - 1);
    }

    private static boolean judge(int[] arr, int l, int r)
    {
        if (l >= r) return true;
        int idx;
        for (idx = l; idx < r; idx++)
            if (arr[idx] > arr[r])
                break;
        for (int i = idx; i < r; i++)
            if (arr[i] < arr[r])
                return false;
        return judge(arr, l, idx - 1) && judge(arr, idx, r - 1);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N;
        N = in.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD174 判断一棵二叉树是否为搜索二叉树和完全二叉树

/* 模拟 */
public class CD174_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static void solution(TreeNode root)
    {
        System.out.println(judgeBinSearch(root));
        System.out.println(judgeBinComplete(root));
    }

    public static boolean judgeBinSearch(TreeNode root)
    {
        ArrayList<Integer> temp = new ArrayList<>();
        inOrder(root, temp);
        for (int i = 0; i < temp.size() - 1; i++)
            if (temp.get(i) > temp.get(i + 1))
                return false;
        return true;
    }

    public static void inOrder(TreeNode root, ArrayList<Integer> temp)
    {
        if (root == null) return;
        inOrder(root.left, temp);
        temp.add(root.val);
        inOrder(root.right, temp);
    }

    public static boolean judgeBinComplete(TreeNode root)
    {
        if (root == null) return true;
        boolean res = true;
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        while (!que.isEmpty())
        {
            TreeNode pollNode = que.poll();
            if (pollNode.left != null)
            {
                if (!res) return res;
                que.add(pollNode.left);
            }
            else res = false;
            if (pollNode.right != null)
            {
                if (!res) return res;
                que.add(pollNode.right);
            }
            else res = false;
        }
        return true;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        solution(rootNode);
    }
}

CDXXX 通过有序数组生成平衡搜索二叉树

public Node generateTree(int[] sortArr) 
{
    if (sortArr == null) return null;
    return generate(sortArr, 0, sortArr.length - 1);
}
public Node generate(int[] sortArr, int start, int end) 
{
    if (start > end) return null;
    int mid = (start + end) / 2;
    Node head = new Node(sortArr[mid]);
    head.left = generate(sortArr, start, mid - 1);
    head.right = generate(sortArr, mid + 1, end);
    return head;
}

CD175 在二叉树中找到一个节点的后继节点

/* 模拟 */
public class CD175_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode parent;

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

        public static TreeNode createTree(int[][] edges, int root, int NUM)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                {
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                    treeNodes[edges[i][1]].parent = treeNodes[edges[i][0]];
                }
                if (edges[i][2] != 0)
                {
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
                    treeNodes[edges[i][2]].parent = treeNodes[edges[i][0]];
                }
            }
            treeNodes[root].parent = null;
            return treeNodes[NUM];
        }
    }

    public static int solution(TreeNode root)
    {
        if (root.right != null)
            return getMostLeft(root.right);
        else
        {
            TreeNode parent = root.parent;
            while (parent != null && parent.left != root)
            {
                root = parent;
                parent = root.parent;
            }
            return parent == null ? 0 : parent.val;
        }
    }

    public static int getMostLeft(TreeNode root)
    {
        while (root.left != null)
            root = root.left;
        return root.val;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root, NUM;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        NUM = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root, NUM);
        System.out.println(solution(rootNode));
    }
}

CD176 在二叉树中找到两个节点的最近公共祖先

/* 递归 */
public class CD176_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root, int o1, int o2)
    {
        if (root == null) return -1;
        int left = solution(root.left, o1, o2);
        int right = solution(root.right, o1, o2);
        if (root.val == o1 || root.val == o2)
            return root.val;
        if (left != -1 && right != -1)
            return root.val;
        return left != -1 ? left : right;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root, o1, o2;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        o1 = in.nextInt();
        o2 = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode, o1, o2));
    }
}

CD177 在二叉树中找到两个节点的最近公共祖先(进阶)

/* hashMap */
public class CD177_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static HashMap<Integer, Integer> map = null;

    public static int solution(TreeNode root, int o1, int o2)
    {
        ArrayList<Integer> temp = new ArrayList<>();
        if (map == null)
        {
            map = new HashMap<>();
            if (root != null) map.put(root.val, -1);
            createMap(root, map);
        }
        while (o1 != -1)
        {
            temp.add(o1);
            o1 = map.get(o1);
        }
        while (o2 != -1)
        {
            if (temp.contains(o2)) return o2;
            o2 = map.get(o2);
        }
        return -1;
    }

    public static void createMap(TreeNode root, HashMap<Integer, Integer> map)
    {
        if (root == null) return;
        if (root.left != null)
            map.put(root.left.val, root.val);
        if (root.right != null)
            map.put(root.right.val, root.val);
        createMap(root.left, map);
        createMap(root.right, map);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root, o1, o2;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        N = in.nextInt();
        while (N-- > 0)
        {
            o1 = in.nextInt();
            o2 = in.nextInt();
            out.println(solution(rootNode, o1, o2));
        }
        out.flush();
    }
}

/*
 * 建立任意两个节点之间的最近公共祖先记录
 * 1. 子树的头节点为 h,h 所有的后代节点和 h 节点的最近公共祖先都是 h
 * 2. h 左子树的每个节点和 h 右子树的每个节点的最近公共祖先都是 h
 * ( 左神的递归有点绕, 不过我的很丑陋:) )
 */
public class CD177_2
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static HashMap<Integer, HashMap<Integer, Integer>> map = null;

    public static int solution(TreeNode root, int o1, int o2)
    {
        if (map == null)
        {
            map = new HashMap<>();
            createMap(root, map);
        }
        return map.get(o1).get(o2);
    }

    public static void createMap(TreeNode root, HashMap<Integer, HashMap<Integer, Integer>> map)
    {
        if (root == null) return;
        ArrayList<Integer> left = new ArrayList<>();
        ArrayList<Integer> right = new ArrayList<>();
        order(root.left, left);
        order(root.right, right);
        if (!map.containsKey(root.val))
            map.put(root.val, new HashMap<>());
        left.add(root.val);
        for (int l : left)
        {
            if (!map.containsKey(l))
                map.put(l, new HashMap<>());
            map.get(l).put(l, l);
            map.get(l).put(root.val, root.val);
            map.get(root.val).put(l, root.val);
            for (int r : right)
            {
                if (!map.containsKey(r))
                    map.put(r, new HashMap<>());
                map.get(r).put(r, r);
                map.get(r).put(root.val, root.val);
                map.get(root.val).put(r, root.val);
                map.get(l).put(r, root.val);
                map.get(r).put(l, root.val);
            }
        }
        createMap(root.left, map);
        createMap(root.right, map);
    }

    public static void order(TreeNode root, ArrayList<Integer> temp)
    {
        if (root == null) return;
        temp.add(root.val);
        order(root.left, temp);
        order(root.right, temp);
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root, o1, o2;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        N = in.nextInt();
        while (N-- > 0)
        {
            o1 = in.nextInt();
            o2 = in.nextInt();
            out.println(solution(rootNode, o1, o2));
        }
        out.flush();
    }
}

CD178 Tarjan 算法与并查集解决二叉树节点间最近公共祖先的批量查询问题❗

/* ❗与左神思路大体相同❗ */
public class CD178_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static class Query
    {
        public int o1;
        public int o2;

        public Query(int o1, int o2)
        {
            this.o1 = o1;
            this.o2 = o2;
        }
    }

    public static int[] solution(TreeNode root, Query[] ques, int nodeNum)
    {
        HashMap<Integer, LinkedList<Integer>> queryMap = new HashMap<>();
        HashMap<Integer, LinkedList<Integer>> indexMap = new HashMap<>();
        HashMap<Integer, Integer> visMap = new HashMap<>();
        int[] ans = new int[ques.length];
        int[] f = new int[nodeNum + 1];
        Arrays.fill(f, -1);
        int o1, o2;
        for (int i = 0; i != ans.length; i++)
        {
            o1 = ques[i].o1;
            o2 = ques[i].o2;

            if (!queryMap.containsKey(o1))
            {
                queryMap.put(o1, new LinkedList<Integer>());
                indexMap.put(o1, new LinkedList<Integer>());
            }
            if (!queryMap.containsKey(o2))
            {
                queryMap.put(o2, new LinkedList<Integer>());
                indexMap.put(o2, new LinkedList<Integer>());
            }
            queryMap.get(o1).add(o2);
            indexMap.get(o1).add(i);
            queryMap.get(o2).add(o1);
            indexMap.get(o2).add(i);
        }
        order(root, ans, queryMap, indexMap, visMap, f);
        return ans;
    }

    public static void order(TreeNode root, int[] ans, HashMap<Integer, LinkedList<Integer>> queryMap, HashMap<Integer, LinkedList<Integer>> indexMap, HashMap<Integer, Integer> visMap, int[] f)
    {
        if (root == null) return;
        order(root.left, ans, queryMap, indexMap, visMap, f);
        if (root.left != null)
        {
            union(f, root.left.val, root.val);
            visMap.put(root.left.val, 1);
        }
        order(root.right, ans, queryMap, indexMap, visMap, f);
        if (root.right != null)
        {
            union(f, root.right.val, root.val);
            visMap.put(root.right.val, 1);
        }
        LinkedList<Integer> nodes = queryMap.get(root.val);
        LinkedList<Integer> idxs = indexMap.get(root.val);
        while (nodes != null && !nodes.isEmpty())
        {
            int node = nodes.poll();
            int idx = idxs.poll();
            if (visMap.containsKey(node))
                ans[idx] = find(f, node);
        }
    }

    public static int find(int[] f, int node)
    {
        if (f[node] == -1)
            return node;
        else
            f[node] = find(f, f[node]);
        return f[node];
    }

    public static void union(int[] f, int u1, int u2)
    {
        int p1 = find(f, u1);
        int p2 = find(f, u2);
        if (p1 != p2)
            f[p1] = p2;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root, o1, o2, M;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        M = in.nextInt();
        Query[] queries = new Query[M];
        for (int i = 0; i < M; i++)
        {
            o1 = in.nextInt();
            o2 = in.nextInt();
            queries[i] = new Query(o1, o2);
        }
        int[] res = solution(rootNode, queries, N);
        Arrays.stream(res).forEach(out::println);
        out.flush();
    }
}

CD179 二叉树节点间的最大距离问题⭐

/* ⭐树的直径(树形DP)⭐ */
public class CD179_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root)
    {
        return posOrder(root)[0];
    }

    public static int[] posOrder(TreeNode root)
    {
        if (root == null) return new int[]{0, 0};
        if (root.left == null && root.right == null) return new int[]{1, 1};
        int[] leftHeight = posOrder(root.left);
        int[] rightHeight = posOrder(root.right);
        return new int[]{Math.max(Math.max(leftHeight[0], rightHeight[0]), leftHeight[1] + rightHeight[1] + 1), Math.max(leftHeight[1], rightHeight[1]) + 1};
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        out.println(solution(rootNode));
        out.flush();
    }
}

/* ⭐递归⭐ */
public class CD179_2
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

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

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root)
    {
        if (root == null) return 0;
        int l = calHeight(root.left);
        int r = calHeight(root.right);
        return Math.max(Math.max(solution(root.left), solution(root.right)), l + r + 1);
    }


    public static int calHeight(TreeNode root)
    {
        if (root == null) return 0;
        if (root.left == null && root.right == null) return 1;
        int leftHeight = calHeight(root.left);
        int rightHeight = calHeight(root.right);
        return Math.max(leftHeight, rightHeight) + 1;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        out.println(solution(rootNode));
        out.flush();
    }
}

CD187 派对的最大快乐值

/* 树形DP */
public class CD187_1
{

    public static int[] solution(int root, ArrayList<Integer>[] edges, int[] happy)
    {
        int curNo = 0, curYes = 0;
        for (int node : edges[root])
        {
            int[] res = solution(node, edges, happy);
            curNo += Math.max(res[0], res[1]);
            curYes += res[1];
        }
        return new int[]{curYes + happy[root], curNo};
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root, f, t;
        N = in.nextInt();
        root = in.nextInt();
        int[] happy = new int[N + 1];
        for (int i = 1; i <= N; i++)
            happy[i] = in.nextInt();
        ArrayList<Integer>[] edges = new ArrayList[N + 1];
        Arrays.setAll(edges, e -> new ArrayList<Integer>());
        for (int i = 1; i < N; i++)
        {
            f = in.nextInt();
            t = in.nextInt();
            edges[f].add(t);
        }
        int[] res = solution(root, edges, happy);
        out.println(Math.max(res[0], res[1]));
        out.flush();
    }
}

CD180 通过先序和中序数组生成后序数组

/* 递归 */
public class CD180_1
{

    public static int[] solution(int[] pre, int[] in)
    {
        int[] ans = new int[pre.length];
        CreateByPreAndIn(pre, 0, pre.length - 1, in, 0, in.length - 1, ans, pre.length - 1);
        return ans;
    }

    public static void CreateByPreAndIn(int[] pre, int ps, int pe, int[] in, int is, int ie, int[] ans, int ansIdx)
    {
        if (ps > pe) return;
        int idx, len;
        for (idx = is; idx <= ie; idx++)
            if (in[idx] == pre[ps])
                break;
        ans[ansIdx] = in[idx];
        len = idx - is;
        CreateByPreAndIn(pre, ps + 1, ps + len, in, is, idx - 1, ans, ansIdx - pe + ps + len - 1);
        CreateByPreAndIn(pre, ps + len + 1, pe, in, idx + 1, ie, ans, ansIdx - 1);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[] preOrder = new int[N];
        for (int i = 0; i < N; i++)
            preOrder[i] = in.nextInt();
        int[] inOrder = new int[N];
        for (int i = 0; i < N; i++)
            inOrder[i] = in.nextInt();
        int[] res = solution(preOrder, inOrder);
        out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
        out.flush();
    }
}

CD181 统计和生成所有不同的二叉树⭐

/* ⭐思维(递推)⭐ */
public class CD181_1
{

    public static long solution(int n)
    {
        long MOD = (long) (1E9 + 7);
        if (n <= 0) return 0;
        long[] ans = new long[10000 + 5];
        ans[0] = 1;
        ans[1] = 1;
        ans[2] = 2;
        for (int i = 3; i <= n; i++)
        {
            for (int j = 0; j < i; j++)
                ans[i] = (ans[i] + ans[j] * ans[i - j - 1]) % MOD;
        }
        return ans[n];
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        out.println(solution(N));
        out.flush();
    }
}

/* ⭐生成所有二叉树⭐ */
public class CD181_2
{

    public static class Node
    {
        public int val;
        public Node left;
        public Node right;

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

    public static List<Node> solution(int n)
    {
        return generate(1, n);
    }

    public static List<Node> generate(int start, int end)
    {
        List<Node> res = new LinkedList<Node>();
        if (start > end)
        {
            res.add(null);
        }
        Node head = null;
        for (int i = start; i < end + 1; i++)
        {
            head = new Node(i);
            List<Node> lSubs = generate(start, i - 1);
            List<Node> rSubs = generate(i + 1, end);
            for (Node l : lSubs)
            {
                for (Node r : rSubs)
                {
                    head.left = l;
                    head.right = r;
                    res.add(cloneTree(head));
                }
            }
        }
        return res;
    }

    public static Node cloneTree(Node head)
    {
        if (head == null) return null;
        Node res = new Node(head.val);
        res.left = cloneTree(head.left);
        res.right = cloneTree(head.right);
        return res;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        solution(N)
        out.flush();
    }
}

CD182 统计和生成所有不同的二叉树(进阶)

/* 数学
 * ans = (C(2n, n) / (n+1)) % MOD
 *     = (C(2n, n) * inv(n+1)) % MOD
 */
public class CD182_1
{

    public static long solution(int n)
    {
        long ans = 1, MOD = (long) (1E9 + 7);
        long[] inv = new long[n + 5];
        inv[1] = 1;
        for (int i = 2; i <= n + 1; i++)
            inv[i] = ((MOD - MOD / i) * inv[(int) (MOD % i)]) % MOD;
        for (int i = n + 1; i <= 2 * n; i++)
            ans = (ans * ((i * inv[i - n]) % MOD)) % MOD;
        return ((ans % MOD) * inv[n + 1]) % MOD;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        out.println(solution(N));
        out.flush();
    }
}

CDXXX 统计完全二叉树的节点数⭐

public int nodeNum(Node head)
{
    if (head == null) return 0;
    return bs(head, 1, mostLeftLevel(head, 1));
}
public int bs(Node node, int l, int h) 
{
    if (l == h) return 1;
    if (mostLeftLevel(node.right, l + 1) == h) 
    	return (1 << (h - l)) + bs(node.right, l + 1, h);
    else 
    	return (1 << (h - l - 1)) + bs(node.left, l + 1, h);
}
public int mostLeftLevel(Node node, int level) 
{
    while (node != null) 
    {
        level++;
        node = node.left;
    }
    return level - 1;
}
posted @ 2023-11-12 21:42  Vivid-BinGo  阅读(6)  评论(0编辑  收藏  举报