目录
套路实践-给定一颗二叉树的头节点head,返回这颗二叉树是不是平衡二叉树
套路实践-给定一棵二叉树的头节点head,任何俩个节点之间都存在距离,返回整颗二叉树的最大距离
套路实践-给定一棵二叉树的头节点head,返回这颗二叉树中最大的二叉搜索子树的头节点。(返回size)
题目一:俩种袋子装苹果,一个装6个,一个装8个。问N个苹果,返回至少使用袋子的数量。
题目二:N份青草,牛先吃,羊后吃。每次吃4的某次方,谁先吃完谁获胜。问给定N,返回谁赢
题目三:定义一种数,可以表示成若干连续整数和的数(数量>1)。
二叉树
二叉树的先序、中序、后续遍历
先序:任何子树的处理顺序都是,先头结点、再左子树、然后右子树
中序:任何子树的处理顺序都是,先左子树、再头节点、然后右子树
后序:任何子树的处理顺序都是,先左子树、再右子树、然后头节点
递归方式实现
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
public static void f(Node head) {
if (head == null) {
return;
}
// 1
f(head.left);
// 2
f(head.right);
// 3
}
// 先序打印所有节点
public static void pre(Node head) {
if (head == null) {
return;
}
System.out.println(head.value);
pre(head.left);
pre(head.right);
}
public static void in(Node head) {
if (head == null) {
return;
}
in(head.left);
System.out.println(head.value);
in(head.right);
}
public static void pos(Node head) {
if (head == null) {
return;
}
pos(head.left);
pos(head.right);
System.out.println(head.value);
}
什么是递归序
非递归方式实现
先序非递归实现
头 弹出打印 右孩子 左孩子 弹 右 左
后序非递归实现
俩个栈实现方式
一个栈实现方式(用变量去卡边界)
// H 等于 head c 等于 null // H 永远跟踪 上次打印的节点
public static void pos2(Node h) {
// H 等于 head c 等于 null
// H 永远跟踪 上次打印的节点
System.out.print("pos-order: ");
if (h != null) {
Stack<Node> stack = new Stack<Node>();
stack.push(h);
Node c = null;
while (!stack.isEmpty()) {
c = stack.peek();
// 左孩子不等于null h不等于左孩子 h不等于右孩子
if (c.left != null && h != c.left && h != c.right) {
stack.push(c.left);
// 右孩子不等于null h 不等于右孩子
} else if (c.right != null && h != c.right) {
stack.push(c.right);
} else {
System.out.print(stack.pop().value + " ");
h = c;
}
}
}
System.out.println();
}
中序非递归实现
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
public static void pre(Node head) {
System.out.print("pre-order: ");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
stack.add(head);
//判断栈是否为空
while (!stack.isEmpty()) {
head = stack.pop();
System.out.print(head.value + " ");
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
}
System.out.println();
}
public static void in(Node cur) {
System.out.print("in-order: ");
if (cur != null) {
Stack<Node> stack = new Stack<Node>();
while (!stack.isEmpty() || cur != null) {
if (cur != null) {
stack.push(cur);
// 来到
cur = cur.left;
} else {
cur = stack.pop();
System.out.print(cur.value + " ");
cur = cur.right;
}
}
}
System.out.println();
}
public static void pos1(Node head) {
//利用俩个栈实现 头(弹) 左 右
// 后一个逆序写出 也就是pop出来 栈先进后出
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>();
s1.push(head);
while (!s1.isEmpty()) {
head = s1.pop(); // 头 右 左
s2.push(head);
if (head.left != null) {
s1.push(head.left);
}
if (head.right != null) {
s1.push(head.right);
}
}
// 左 右 头
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
System.out.println();
}
// 一个栈实现后序遍历
public static void pos2(Node h) {
// H 等于 head c 等于 null
// H 永远跟踪 上次打印的节点
System.out.print("pos-order: ");
if (h != null) {
Stack<Node> stack = new Stack<Node>();
stack.push(h);
Node c = null;
while (!stack.isEmpty()) {
c = stack.peek();
// 左孩子不等于null h不等于左孩子 h不等于右孩子
if (c.left != null && h != c.left && h != c.right) {
stack.push(c.left);
// 右孩子不等于null h 不等于右孩子
} else if (c.right != null && h != c.right) {
stack.push(c.right);
} else {
System.out.print(stack.pop().value + " ");
h = c;
}
}
}
System.out.println();
}
实现二叉树的按层遍历
1)其实就是宽度优先遍历,用队列
2)可以通过设置flag变量的方式,来发现某一层的结束(看题目)
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
public static void level(Node head) {
if (head == null) {
return;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.value);
if (cur.left != null) {
queue.add(cur.left);
}
if (cur.right != null) {
queue.add(cur.right);
}
}
}
求二叉树的最大宽度
HashMap方式
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
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); // head 在第一层
int curLevel = 1; //当前你正在统计哪一层的宽度
int curLevelNodes = 0; //当前层curLeve1层, 宽度目前是多少.
int max = 0;
while (!queue.isEmpty()) {
Node cur = queue.poll();
// curNodeLevel 获取当前值的层数
int curNodeLevel = levelMap.get(cur);
if (cur.left != null) {
levelMap.put(cur.left, curNodeLevel + 1);
qu