输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
/**
* @description 剑指 Offer 26. 树的子结构
* @author HelloWorld
* @create 2023/7/23 06:56
* @param A
* @param B
* @return boolean
*/
public boolean isSubStructure(TreeNode A, TreeNode B) {
boolean result = false;
if (null == A || null == B) {
return result;
}
return compare(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private boolean compare(TreeNode A, TreeNode B) {
if (null == B) {
return true;
}
if (null == A) {
return false;
}
if (A.val != B.val) {
return false;
}
return compare(A.left, B.left) && compare(A.right, B.right);
}
/**
* @description 剑指 Offer 26. 树的子结构 非递归实现
* @author HelloWorld
* @create 2023/7/23 10:21
* @param A
* @param B
* @return boolean
*/
public boolean isSubStructureIter(TreeNode A, TreeNode B) {
if (null == A || null == B) {
return false;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(A);
while (!stack.isEmpty()) {
TreeNode treeNode = stack.pop();
if (treeNode.val == B.val && compareIter(treeNode, B)) {
return true;
}
addIfNotNull(stack, treeNode.right);
addIfNotNull(stack, treeNode.left);
}
return false;
}
private boolean compareIter(TreeNode A, TreeNode B) {
Stack<TreeNode> stackA = new Stack<>();
Stack<TreeNode> stackB = new Stack<>();
stackA.push(A);
stackB.push(B);
while (!stackA.isEmpty() && !stackB.isEmpty()) {
TreeNode treeNodeA = stackA.pop();
TreeNode treeNodeB = stackB.pop();
if (null == treeNodeB) {
continue;
}
if (null == treeNodeA || treeNodeA.val != treeNodeB.val) {
return false;
}
stackA.push(treeNodeA.left);
stackA.push(treeNodeA.right);
stackB.push(treeNodeB.left);
stackB.push(treeNodeB.right);
}
return true;
}
private void addIfNotNull(Collection<TreeNode> collection, TreeNode treeNode) {
if (null != treeNode) {
collection.add(treeNode);
}
}
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
先获取镜像后的遍历结果,再去构建二叉树
/**
* @description 二叉树的镜像
* @author HelloWorld
* @create 2023/7/23 10:26
* @param root
* @return com.wy.leetcode.practise_30.TreeNode
*
*/
public TreeNode mirrorTree(TreeNode root) {
if (null == root) {
return root;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
List<Integer> result = new ArrayList<>();
while (!queue.isEmpty()) {
int size = queue.size();
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < size; i++) {
TreeNode treeNode = queue.poll();
if (null != treeNode) {
list.addFirst(treeNode.val);
queue.add(treeNode.left);
queue.add(treeNode.right);
} else {
list.addFirst(null);
}
}
result.addAll(list);
}
return initTree(result);
}
private TreeNode initTree(List<Integer> list) {
TreeNode root = new TreeNode(list.get(0));
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int i = 1;
while (!queue.isEmpty() && i < list.size()) {
TreeNode treeNode = queue.poll();
if (null != list.get(i)) {
treeNode.left = new TreeNode(list.get(i));
queue.add(treeNode.left);
}
i++;
if (i < list.size() && null != list.get(i)) {
treeNode.right = new TreeNode(list.get(i));
queue.add(treeNode.right);
}
i++;
}
return root;
}
/**
* @description 二叉树的镜像
* @author HelloWorld
* @create 2023/7/23 10:26
* @param root
* @return com.wy.leetcode.practise_30.TreeNode
*
* 本质是交换每一层级的左右节点
*/
public TreeNode mirrorTree(TreeNode root) {
if (null == root) {
return root;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < size; i++) {
TreeNode treeNode = queue.poll();
// 交换左右节点
TreeNode temp = treeNode.left;
treeNode.left = treeNode.right;
treeNode.right = temp;
if (null != treeNode.left) { queue.offer(treeNode.left);}
if (null != treeNode.right) { queue.offer(treeNode.right);}
}
}
return root;
}
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个[1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
/**
* @description 剑指 Offer 28. 对称的二叉树
* @author HelloWorld
* @create 2023/7/23 14:28
* @param root
* @return boolean
*/
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
Queue<TreeNode> queueA = new LinkedList<>();
Queue<TreeNode> queueB = new LinkedList<>();
queueA.offer(root.left);
queueB.offer(root.right);
while (!queueA.isEmpty() && !queueB.isEmpty()) {
int size = queueA.size();
if (size != queueB.size()) {
return false;
}
for (int i = 0; i < size; i++) {
TreeNode treeNodeA = queueA.poll();
TreeNode treeNodeB = queueB.poll();
if (treeNodeB == null && treeNodeA == null) {
continue;
}
if (treeNodeB == null || treeNodeA == null || treeNodeA.val != treeNodeB.val) {
return false;
}
queueA.offer(treeNodeA.left);
queueA.offer(treeNodeA.right);
queueB.offer(treeNodeB.right);
queueB.offer(treeNodeB.left);
}
}
return queueA.isEmpty() && queueB.isEmpty();
}
package com.wy.leetcode.practise_30;
import java.util.*;
/**
* @author yuyang.zhang
* @Description
* @date 2023/7/21
*/
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
/**
* @description 根据层次遍历的结果还原二叉树
* 层次遍历结果:3,9,20,null,null,15,7
* 3
* / \
* 9 20
* / \
* 15 7
* @author HelloWorld
* @create 2023/7/22 09:16
* @param values
* @return com.wy.leetcode.practise_30.TreeNode
*/
public static TreeNode init(Integer ...values) {
TreeNode root = new TreeNode(values[0]);
Queue<TreeNode> treeNodeQueue = new LinkedList<>();
treeNodeQueue.add(root);
int i = 1;
while (!treeNodeQueue.isEmpty() && i < values.length) {
TreeNode treeNode = treeNodeQueue.poll();
// 左孩子是否存在
if (values[i] != null) {
treeNode.left = new TreeNode(values[i]);
treeNodeQueue.add(treeNode.left);
}
i++;
if (i < values.length && values[i] != null) {
treeNode.right = new TreeNode(values[i]);
treeNodeQueue.add(treeNode.right);
}
i++;
}
return root;
}
/**
* @description 层次遍历
* @author HelloWorld
* @create 2023/7/23 08:56
* @param root
* @return java.util.List
*/
public static List<Integer> levelOrderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
result.add(treeNode.val);
addIfNotNull(queue, treeNode.left);
addIfNotNull(queue, treeNode.right);
}
return result;
}
/**
* @description 前序遍历:根,左,右
* @author HelloWorld
* @create 2023/7/23 08:58
* @param root
* @return void
*/
public static List<Integer> preOrderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
result.add(node.val);
addIfNotNull(stack, node.right);
addIfNotNull(stack, node.left);
}
return result;
}
/**
* @description 中序遍历 左根右
* @author HelloWorld
* @create 2023/7/23 09:20
* @param root
* @return java.util.List
*/
public static List<Integer> inOrderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
while (null != node || !stack.isEmpty()) {
while (null != node) {
stack.push(node);
node = node.left;
}
node= stack.pop();
result.add(node.val);
node = node.right;
}
return result;
}
/**
* @description 后续遍历
* @author HelloWorld 左右根
* @create 2023/7/23 09:09
* @param node
* @return java.util.List
*/
public static List<Integer> postOrderTraversal(TreeNode node) {
Stack<TreeNode> resultStack = new Stack<>();
Stack<TreeNode> stack = new Stack<>();
stack.add(node);
while (!stack.isEmpty()) {
TreeNode treeNode = stack.pop();
resultStack.push(treeNode);
addIfNotNull(stack, treeNode.left);
addIfNotNull(stack, treeNode.right);
}
List<Integer> result = new ArrayList<>();
while (!resultStack.isEmpty()) {
result.add(resultStack.pop().val);
}
return result;
}
private static void addIfNotNull(Collection<TreeNode> collection, TreeNode node) {
if (null != node) {
collection.add(node);
}
}
public static void main(String[] args) {
TreeNode node = init(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<Integer> integers = levelOrderTraversal(node);
for (Integer integer : integers) {
System.out.println(integer);
}
}
}