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;
}