第一题
Leetcode
- Encode N-ary Tree to Biary Tree
package com.lzf2.class09;
import java.util.ArrayList;
import java.util.List;
//多叉树 转二叉树
//力扣 431题 https://leetcode.com/problems/encode-n-ary-tree-to-binary-tree
public class EncodeNaryTreeToBinaryTree {
//多叉树结点,提交时不要提交这个类
public static class Node {
public int val;
public List<Node> children;
public Node() {
}
public Node(int val) {
this.val = val;
}
public Node(int val, List<Node> children) {
this.val = val;
this.children = children;
}
}
//二叉树结点,提交时不要提交这个类
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
// 只提交这个类即可
class Codec {
// Encodes an n-ary tree to a binary tree.
public TreeNode encode(Node root){
if (root == null){
return null;
}
TreeNode head = new TreeNode(root.val);
head.left = en(root.children);
return head;
}
public TreeNode en(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 = en(child.children);
}
return head;
}
// Decodes your binary tree to an n-ary tree.
public Node decode(TreeNode root){
if (root == null){
return null;
}
return new Node(root.val,de(root.left));
}
public 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;
}
}
}
第二题
求二叉树最宽的层有多少个节点
在按层遍历的基础上,如果能够知道当前层是否结束,就能求出最宽的层有多少个节点。
利用一下几个有限的变量就可以建立这样的机制
Node curEnd = head;//当前层,最右一个节点是谁
Node nextEnd = null;//下一层,最右一个节点是谁
int max = 0;
int curLevelNodes = 0;//当前层的节点数
package com.lzf2.class09;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
/**
* 求树的最大宽度
*/
public class TreeMaxWidth {
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
public static int maxWidthUseMap(Node head) {
if (head == null) {
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
// key 在 哪一层,value
HashMap<Node, Integer> levelMap = new HashMap<>();
levelMap.put(head, 1);
int curLevel = 1; // 当前你正在统计哪一层的宽度
int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少
int max = 0;
while (!queue.isEmpty()) {
Node cur = queue.poll();
int curNodeLevel = levelMap.get(cur);
if (cur.left != null) {
levelMap.put(cur.left, curNodeLevel + 1);
queue.add(cur.left);
}
if (cur.right != null) {
levelMap.put(cur.right, curNodeLevel + 1);
queue.add(cur.right);
}
if (curNodeLevel == curLevel) {
curLevelNodes++;
} else {
max = Math.max(max, curLevelNodes);
curLevel++;
curLevelNodes = 1;
}
}
max = Math.max(max, curLevelNodes);
return max;
}
public static int maxWidthNoMap(Node head){
if (head == null){
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
Node curEnd = head;//当前层,最右一个节点是谁
Node nextEnd = null;//下一层,最右一个节点是谁
int max = 0;
int curLevelNodes = 0;//当前层的节点数
while (!queue.isEmpty()){
Node cur = queue.poll();
if (cur.left != null){
queue.add(cur.left);
nextEnd = cur.left;
}
if (cur.right != null){
queue.add(cur.right);
nextEnd = cur.right;
}
curLevelNodes++;
if (cur == curEnd){
max =Math.max(max,curLevelNodes);
curLevelNodes = 0;
curEnd = nextEnd;
}
}
return max;
}
// for test
public static Node generateRandomBST(int maxLevel, int maxValue) {
return generate(1, maxLevel, maxValue);
}
// for test
public static Node generate(int level, int maxLevel, int maxValue) {
if (level > maxLevel || Math.random() < 0.5) {
return null;
}
Node head = new Node((int) (Math.random() * maxValue));
head.left = generate(level + 1, maxLevel, maxValue);
head.right = generate(level + 1, maxLevel, maxValue);
return head;
}
public static void main(String[] args) {
int maxLevel = 10;
int maxValue = 100;
int testTimes = 1000000;
for (int i = 0; i < testTimes; i++) {
Node head = generateRandomBST(maxLevel, maxValue);
if (maxWidthUseMap(head) != maxWidthNoMap(head)) {
System.out.println("Oops!");
}
}
System.out.println("finish!");
}
}
第三题
给你二叉树中的某个节点,返回该节点的后继节点
二叉树结构如下定义:
Class Node {
V value;
Node left;
Node right;
Node parent;
}
给你二叉树中的某个节点,返回该节点的后继节点中序遍历序列中,某个结点的下一个结点就在它后面。可以先对该树进行中序遍历,然后找到某个结点的位置,就可以知道他的后继结点了。比较low时间复杂度为O(n)
/**
* 给你二叉树中的某个节点,返回该节点的后继节点
*
* 二叉树结构如下定义:
* Class Node {
* V value;
* Node left;
* Node right;
* Node parent;
* }
* 给你二叉树中的某个节点,返回该节点的后继节点
*
*
* x有右树,右树的最左节点就是x的后继节点
* 无右树,x一直往上看,如果自己的父节点的右孩子,继续往上,
* 直到自己是父节点的左孩子,如果没有则x没有后继节点
*/
public class SuccessorNode {
public static class Node{
public int value;
public Node parent;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
public static Node getSuccessorNode(Node node){
if (node == null){
return node;
}
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;
}
}
//返回node的最左节点
public static Node getLeftMost(Node node){
if (node == null){
return node;
}
while (node.left != null){
node = node.left;
}
return node;
}
public static void main(String[] args) {
Node head = new Node(6);
head.parent = null;
head.left = new Node(3);
head.left.parent = head;
head.left.left = new Node(1);
head.left.left.parent = head.left;
head.left.left.right = new Node(2);
head.left.left.right.parent = head.left.left;
head.left.right = new Node(4);
head.left.right.parent = head.left;
head.left.right.right = new Node(5);
head.left.right.right.parent = head.left.right;
head.right = new Node(9);
head.right.parent = head;
head.right.left = new Node(8);
head.right.left.parent = head.right;
head.right.left.left = new Node(7);
head.right.left.left.parent = head.right.left;
head.right.right = new Node(10);
head.right.right.parent = head.right;
Node test = head.left.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.left.left.right;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.left.right;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.left.right.right;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.right.left.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.right.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.right;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
test = head.right.right; // 10's next is null
System.out.println(test.value + " next: " + getSuccessorNode(test));
}
}
第四题
请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。 如果从纸条的下边向上方连续对折2次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。
给定一个输入参数N,代表纸条都从下边向上方连续对折N次。 请从上到下打印所有折痕的方向。
例如:N=1时,打印: down N=2时,打印: down down up
public class PaperFolding {
public static void printAllFolds(int N){
process(1,N,true);
}
//当前节点在第 i 层,一共N层(N固定不变)
//这个节点是凹的话 down为 T
//这个节点是凸的化 down为 F
private static void process(int i, int N, boolean down) {
// base case
if (i > N){
return;
}
process(i + 1,N,true);
System.out.print(down ? "凹 " : "凸 ");
process(i + 1,N,false);
}
public static void main(String[] args) {
int N = 3;
printAllFolds(N);
}
}