1. 多叉树 序列化 成二叉树
父节点的子节点,放在左树右边界上,或者放在右树左边界上
/**
* 多叉树 序列化 成二叉树
* 父节点的子节点,放在左树右边界上,或者放在右树左边界上
*/
public BiNode serializeTree(TreeNode node) {
if (node == null) {
return null;
}
BiNode node1 = new BiNode(node.value);
if (node.children.size() == 0) {
return node1;
}
node1.left = serializeTree(node.children.get(0));
BiNode curr = node1.left;
for (int i = 1; i < node.children.size(); i++) {
TreeNode c = node.children.get(i);
curr.right = serializeTree(c);
curr = curr.right;
}
return node1;
}
public TreeNode unSerializeTree(BiNode node) {
if (node == null) {
return null;
}
TreeNode tnode = new TreeNode(node.value);
if (node.left == null) {
return tnode;
}
BiNode curr = node.left;
while (curr != null) {
tnode.children.add(unSerializeTree(curr));
curr = curr.right;
}
return tnode;
}
@Test
public void test1() {
for (int i = 0; i < 10000; i++) {
TreeNode tNode = Reduce.treeNode(3, 100);
BiNode node1 = serializeTree(tNode);
TreeNode tNode2 = unSerializeTree(node1);
if (!CompareUtil.compare(tNode, tNode2)) {
System.out.println(Printer.print(node1));
return;
}
}
}
2. 二叉树最宽的层有多少节点
一种是按层遍历,设置两个指针,表示开始指针和结束指针
一种是直接将下一层放到一个队列中
public int maxLevelLength(BiNode node) {
if (node == null) {
return 0;
}
Queue<BiNode> queue = new LinkedList<>();
BiNode currEnd = node;
BiNode nextEnd = null;
queue.add(node);
BiNode curr;
int max = 0;
int length = 0;
while (!queue.isEmpty()) {
curr = queue.poll();
if (curr.left != null) {
queue.add(curr.left);
nextEnd = curr.left;
}
if (curr.right != null) {
queue.add(curr.right);
nextEnd = curr.right;
}
length++;
if (curr == currEnd) {
max = Math.max(max, length);
length = 0;
currEnd = nextEnd;
}
}
return max;
}
public int maxLevelLengthCompare(BiNode node) {
if (node == null) {
return 0;
}
int len = 0;
Queue<BiNode> currLevel = new LinkedList<>();
currLevel.add(node);
Queue<BiNode> nextLevel = new LinkedList<>();
Queue<BiNode> temp;
BiNode tempb;
while (!currLevel.isEmpty()) {
len = Math.max(len, currLevel.size());
while (!currLevel.isEmpty()) {
tempb = currLevel.poll();
if (tempb.left != null) {
nextLevel.add(tempb.left);
}
if (tempb.right != null) {
nextLevel.add(tempb.right);
}
}
temp = nextLevel;
nextLevel = currLevel;
currLevel = temp;
}
return len;
}
@Test
public void test2() {
for (int i = 0; i < 10000; i++) {
BiNode node = Reduce.binaryTree(5, 100);
int v1 = maxLevelLength(node);
int v2 = maxLevelLengthCompare(node);
if (v1 != v2) {
System.out.println(Printer.print(node));
System.out.println(v1);
System.out.println(v2);
return;
}
}
}
3. 中序遍历 ,求后继节点
- 中序遍历时,先遍历左树,然后根节点,然后右树
- 所以 左树的 “最右节点” 后面就是根节点
- 根节点的后面一个节点就是右树的“最左节点”
- 既 某个节点 往上找,找到第一个 “我是左节点” 的父节点,就是中序遍历的后继节点
public BiWithPrtNode findNext(BiWithPrtNode node) {
if (node == null) {
return null;
}
if (node.right != null) {
BiWithPrtNode curr = (BiWithPrtNode) node.right;
while (curr.left != null) {
curr = (BiWithPrtNode) curr.left;
}
return curr;
}
while (node.parent != null && node.parent.left != node) {
node = node.parent;
}
return node.parent;
}
public BiWithPrtNode findNextCompare(LinkedList<BiNode> order, BiWithPrtNode node) {
if (node == null) {
return null;
}
int idx = order.indexOf(node);
for (int i = idx + 1; i < order.size(); i++) {
if (order.get(i) != null) {
return (BiWithPrtNode) order.get(i);
}
}
return null;
}
private void middleLoop(BiNode node, Queue<BiNode> order) {
if (node == null) {
order.add(null);
return;
}
middleLoop(node.left, order);
order.add(node);
middleLoop(node.right, order);
}
@Test
public void test3() {
for (int i = 0; i < 10000; i++) {
BiWithPrtNode node = Reduce.binaryTreeWithPrt(5, 100);
LinkedList<BiNode> order = new LinkedList<>();
middleLoop(node, order);
BiWithPrtNode n0 = (BiWithPrtNode) order.get(Reduce.num(0, order.size() - 1));
BiWithPrtNode n1 = findNext(n0);
BiWithPrtNode n2 = findNextCompare(order, n0);
if (n1 != n2) {
System.out.println(Printer.print(node));
System.out.println(n1);
System.out.println(n2);
return;
}
}
}
4. 纸条折痕问题
把一段纸条竖放在桌子上,然后从纸条的下边向上方对折一次,压出折痕后展开。此时折痕是凹下去的。如果从纸条的下边向上方连续对折两次,压出折痕后展开,此时有三条折痕,从上到下依次是凹、凹、凸。
给定一个参数N,代表纸条从下到上连续对折N次。请从上到下打印所有折痕的方向。
public void process(int level, int N, int v, StringBuilder sb) {
if (level >= N) {
return;
}
process(level + 1, N, 0, sb);
sb.append(v == 1 ? "凸" : "凹");
process(level + 1, N, 1, sb);
}
public String foldOrder(int N) {
StringBuilder sb = new StringBuilder();
process(0, N, 0, sb);
return sb.toString();
}
@Test
public void test() {
System.out.println(foldOrder(1));
System.out.println(foldOrder(2));
System.out.println(foldOrder(3));
}