From c9008b25e86f0c77a2a4044d2bfac6089da5a413 Mon Sep 17 00:00:00 2001 From: xiaotiancai893661742 <46739364+xiaotiancai893661742@users.noreply.github.com> Date: Sun, 31 Jul 2022 16:08:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E5=A5=97=E8=B7=AF?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zuolaos/jichuban/Code09_二叉树.java | 366 +++++++++++++----- .../jichuban/Code12_归并排序进阶.java | 4 +- .../zuolaos/jichuban/Code16_多叉数.java | 129 ++++++ 3 files changed, 393 insertions(+), 106 deletions(-) create mode 100644 src/test/java/zuolaos/jichuban/Code16_多叉数.java diff --git a/src/test/java/zuolaos/jichuban/Code09_二叉树.java b/src/test/java/zuolaos/jichuban/Code09_二叉树.java index a4e8bb9..e44ca85 100644 --- a/src/test/java/zuolaos/jichuban/Code09_二叉树.java +++ b/src/test/java/zuolaos/jichuban/Code09_二叉树.java @@ -3,40 +3,285 @@ package zuolaos.jichuban; import java.util.*; -public class Code09_二叉树 { - private static class Node { - Node left; - Node right; - int value; +class Node { + Node left; + Node right; + int value; - public Node(int value) { - this.value = value; + public Node(int value) { + this.value = value; + } +} + +class 搜索二叉树判断 { + private class Info { + int max; + int min; + boolean isBST; + + public Info(int max, int min, boolean isBST) { + this.max = max; + this.min = min; + this.isBST = isBST; + } + + public Info process(Node node) { + if (node == null) { + return null; + } + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + int max = Integer.MIN_VALUE; + int min = Integer.MAX_VALUE; + if (leftInfo != null) { + max = Math.max(max, leftInfo.max); + min = Math.max(min, leftInfo.min); + } + if (rightInfo != null) { + max = Math.max(max, rightInfo.max); + min = Math.max(min, rightInfo.min); + } + boolean isSearch = true; + if (leftInfo != null && (!leftInfo.isBST || leftInfo.max >= node.value)) { + isSearch = false; + } + if (rightInfo != null && (!rightInfo.isBST || rightInfo.min <= node.value)) { + isSearch = false; + } + return new Info(max, min, isSearch); } } +} - private static class Info { +class 平衡二叉树判断 { + private class Info { int height; - boolean isPing; + boolean isBalance; - public Info(int height, boolean isPing) { + public Info(int height, boolean isBanlance) { this.height = height; - this.isPing = isPing; + this.isBalance = isBanlance; } } - private static class Sousuo { - int max; + public Info process(Node node) { + if (node == null) { + return new Info(0, true); + } + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + int h = Math.max(leftInfo.height, rightInfo.height) + 1; + boolean isBalance = true; + if (!leftInfo.isBalance + || !rightInfo.isBalance + || Math.abs(leftInfo.height - rightInfo.height) > 2) { + isBalance = false; + } + return new Info(h, isBalance); + } +} + +class 先序和中序获取树 { + public Node process(int[] pre, int L1, int R1, int[] in, int L2, int R2) { + int root = pre[L1]; + Node node = new Node(root); + if (L1 == R1) { + return node; + } + + int inIndex = 0; + for (int i = L2; i <= R2; i++) { + if (root == in[i]) { + inIndex = i; + break; + } + } + int lcount = inIndex - L2; + int rcount = R2 - inIndex; + node.left = process(pre, L1 + 1, L1 + lcount, in, L2, inIndex - 1); + node.right = process(pre, R1 - rcount + 1, R1, in, inIndex + 1, R2); + return node; + } + + public static void main(String[] args) { + //先 + int[] arr1 = {1, 2, 3, 4, 5, 6, 7}; + int[] arr2 = {3, 2, 4, 1, 6, 5, 7}; + 先序和中序获取树 aaa = new 先序和中序获取树(); + Node node = aaa.process(arr1, 0, arr1.length - 1, arr2, 0, arr2.length - 1); + System.out.println(node); + } +} + + + +class 节点最大距离 { + private class Info { + int h; + int maxDistance; + + public Info(int h, int maxDistance) { + this.h = h; + this.maxDistance = maxDistance; + } + } + + public Info process(Node node) { + if (node == null) { + return new Info(0, 0); + } + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + int h = Math.max(leftInfo.h, rightInfo.h) + 1; + + int p1 = leftInfo.h + leftInfo.h + 1; + int p2 = leftInfo.maxDistance; + int p3 = rightInfo.maxDistance; + int maxDistance = Math.max(p1, Math.max(p2, p3)); + return new Info(h, maxDistance); + } +} + +class 最大的子树是搜索二叉树返回节点 { + + +} +class 最大的子树是搜索二叉树返回大小 { + private class Info { + int maxBSTSubTreeSize; int min; - boolean isSousuo; + int max; + boolean isBST; - public Sousuo(boolean isSousuo, int max, int min) { - this.isSousuo = isSousuo; - this.max = max; + public Info(int maxBSTSubTreeSize, int min, int max, boolean isBST) { + this.maxBSTSubTreeSize = maxBSTSubTreeSize; this.min = min; + this.max = max; + this.isBST = isBST; + } + } + + public Info process(Node node) { + if (node == null) { + return null; + } + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + + int max = node.value; + int min = node.value; + if (leftInfo != null) { + max = Math.max(max, leftInfo.max); + min = Math.max(min, leftInfo.min); + } + if (rightInfo != null) { + max = Math.max(max, rightInfo.max); + min = Math.max(min, rightInfo.min); + } + boolean isBST = true; + if (leftInfo != null && (!leftInfo.isBST || leftInfo.max >= node.value)) { + isBST = false; } + if (rightInfo != null && (!rightInfo.isBST || rightInfo.min <= node.value)) { + isBST = false; + } + int maxBSTSubTreeSize = 0; + int lMaxBSTSubTreeSize = leftInfo == null ? 0 : leftInfo.maxBSTSubTreeSize; + int rMaxBSTSubTreeSize = rightInfo == null ? 0 : rightInfo.maxBSTSubTreeSize; + if (isBST) { + maxBSTSubTreeSize = lMaxBSTSubTreeSize + rMaxBSTSubTreeSize + 1; + } else { + maxBSTSubTreeSize = Math.max(lMaxBSTSubTreeSize, rMaxBSTSubTreeSize); + } + return new Info(maxBSTSubTreeSize, min, max, isBST); + } + + public static void main(String[] args) { + 最大的子树是搜索二叉树返回大小 aaa = new 最大的子树是搜索二叉树返回大小(); + Node node = new Node(2); + node.left = new Node(1); + node.right = new Node(3); + node.right.right = new Node(1); + Info process = aaa.process(node); + System.out.println(process.maxBSTSubTreeSize); + } + +} + +class 完全二叉树判断 { + private class Info { + int h; + boolean isFull; + boolean isCo; + + public Info(int h, boolean isFull, boolean isCo) { + this.h = h; + this.isFull = isFull; + this.isCo = isCo; + } + } + + public Info process(Node node) { + if (node == null) { + return new Info(0, true, true); + } + int h; + boolean isFull; + + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + h = Math.max(leftInfo.h, rightInfo.h) + 1; + isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.h == rightInfo.h; + boolean isCo = false; + if (leftInfo.isFull && rightInfo.isFull && leftInfo.h == rightInfo.h) { + isCo = true; + } else if (leftInfo.isCo && rightInfo.isFull && leftInfo.h == rightInfo.h + 1) { + isCo = true; + } else if (leftInfo.isFull && rightInfo.isFull && leftInfo.h == rightInfo.h + 1) { + isCo = true; + } else if (leftInfo.isFull && rightInfo.isCo && leftInfo.h == rightInfo.h) { + isCo = true; + } + return new Info(h, isFull, isCo); } +} + +class 满二叉树判断 { + private class Info { + int h; + int nodes; + + public Info(int h, int nodes) { + this.h = h; + this.nodes = nodes; + } + } + + public Info process(Node node) { + if (node == null) { + return new Info(0, 0); + } + Info leftInfo = process(node.left); + Info rightInfo = process(node.right); + int h = Math.max(leftInfo.h, rightInfo.h) + 1; + int nodes = leftInfo.nodes + rightInfo.nodes + 1; + return new Info(h, nodes); + } + + + public static void main(String[] args) { + 满二叉树判断 aaa = new 满二叉树判断(); + Info info = aaa.process(null); + //2的h次方 + boolean is = (1 << info.h) - 1 == info.nodes; + } + +} + +public class Code09_二叉树 { + //前序 中序 后序 public static void print(Node head) { if (head == null) { @@ -71,59 +316,6 @@ public class Code09_二叉树 { return heap1.value == heap2.value && isSameTree(heap1.left, heap2.right) && isSameTree(heap2.right, heap2.left); } - - //平衡二叉树的判断 - public static Info isPingHengTree(Node x) { - if (x == null) { - return new Info(0, true); - } - - Info leftInfo = isPingHengTree(x.left); - //todo 可优化 -// if (!leftInfo.isPing) { -// return new Info(0, false); -// } - Info rightInfo = isPingHengTree(x.right); - boolean isping = leftInfo.isPing && rightInfo.isPing && Math.abs(leftInfo.height - rightInfo.height) < 2; - int height = Math.max(leftInfo.height, rightInfo.height) + 1; - return new Info(height, isping); - } - - - //搜索二叉树的判断 - public static Sousuo isSousuoTree(Node x) { - if (x == null) { - return null; - } - Sousuo leftNode = isSousuoTree(x.left); - Sousuo rightNode = isSousuoTree(x.right); - int max = x.value; - int min = x.value; - if (leftNode != null) { - max = Math.max(max, leftNode.max); - min = Math.min(min, leftNode.min); - } - if (rightNode != null) { - max = Math.max(max, rightNode.max); - min = Math.min(min, rightNode.min); - } - - boolean isSousuo = true; - if (leftNode != null && !leftNode.isSousuo) { - isSousuo = false; - } - if (leftNode != null && !leftNode.isSousuo) { - isSousuo = false; - } - boolean leftMaxLessX = leftNode == null ? true : leftNode.max < x.value; - boolean rightMinMoreX = rightNode == null ? true : rightNode.min > x.value; - if (!(leftMaxLessX && rightMinMoreX)) { - isSousuo = false; - } - return new Sousuo(isSousuo, max, min); - } - - //求最大深度 public static int maxDepth(Node node) { if (node == null) { @@ -132,26 +324,6 @@ public class Code09_二叉树 { return Math.max(maxDepth(node.left), maxDepth(node.right)) + 1; } - - //先序数组+中序数组 构造树 - public static Node zhongAndXian(int[] pre, int L1, int R1, int[] in, int L2, int R2) { - if (L1 > R1) { - return null; - } - Node head = new Node(pre[L1]); - if (L1 == R1) { - return head; - } - int find = L2; - //todo 可优化 - while (in[find] != pre[L1]) { - find++; - } - head.left = zhongAndXian(pre, L1 + 1, L1 + find - L2, in, L2, find - 1); - head.right = zhongAndXian(pre, L1 + find - L2 + 1, R1, in, find + 1, R2); - return head; - } - //按层遍历按序输出 public static List> depthNode(Node node) { List> result = new LinkedList<>(); @@ -213,19 +385,5 @@ public class Code09_二叉树 { path.remove(path.size() - 1); } - public static void main(String[] args) { - //先 - int[] arr1 = {1, 2, 3, 4, 5, 6, 7}; - int[] arr2 = {3, 2, 4, 1, 6, 5, 7}; - Node node = zhongAndXian(arr1, 0, arr1.length - 1, arr2, 0, arr2.length - 1); - System.out.println(node); - Node node1 = new Node(1); - node1.left = new Node(2); - node1.left.left = new Node(2); - node1.left.left.left = new Node(2); - node1.right = new Node(2); - System.out.println(isPingHengTree(node1).isPing); - print(node); - } } diff --git a/src/test/java/zuolaos/jichuban/Code12_归并排序进阶.java b/src/test/java/zuolaos/jichuban/Code12_归并排序进阶.java index 6d66eb8..b206ff1 100644 --- a/src/test/java/zuolaos/jichuban/Code12_归并排序进阶.java +++ b/src/test/java/zuolaos/jichuban/Code12_归并排序进阶.java @@ -6,8 +6,8 @@ public class Code12_归并排序进阶 { } -//找到子数组累加和 在lower upper范围内 -class FindZiShuZuSum { +//找到所有子数组累加和,在[lower upper]范围内的子数组个数 +class 子数组累加和在范围内的个数 { public static int start(int[] arr, int lower, int upper) { int[] help = new int[arr.length]; help[0] = arr[0]; diff --git a/src/test/java/zuolaos/jichuban/Code16_多叉数.java b/src/test/java/zuolaos/jichuban/Code16_多叉数.java new file mode 100644 index 0000000..acbac7f --- /dev/null +++ b/src/test/java/zuolaos/jichuban/Code16_多叉数.java @@ -0,0 +1,129 @@ +package zuolaos.jichuban; + +import java.util.ArrayList; +import java.util.List; + +public class Code16_多叉数 { +} + + +class 多叉树序列化和反序列化 { + private class Node { + public int val; + public List children; + + public Node() { + } + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } + } + + // 提交时不要提交这个类 + private class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + //序列化 + public TreeNode encode(Node node) { + if (node == null) { + return null; + } + TreeNode treeNode = new TreeNode(node.val); + treeNode.left = en(node.children); + return treeNode; + } + + private TreeNode en(List children) { + TreeNode head = null; + //上一个节点的位置 + TreeNode last = null; + for (Node child : children) { + TreeNode treeNode = new TreeNode(child.val); + if (head == null) { + head = treeNode; + } else { + last.right = treeNode; + } + last = treeNode; + last.left = en(child.children); + } + return head; + } + + //反序列化 + public Node decode(TreeNode treeNode) { + if (treeNode == null) { + return null; + } + Node node = new Node(treeNode.val, de(treeNode)); + return node; + } + + private List de(TreeNode root) { + List nodes = null; + while (root != null) { + if (nodes == null) { + nodes = new ArrayList<>(); + } + Node cur = new Node(root.val, de(root.left)); + nodes.add(cur); + root = root.right; + } + return nodes; + } + + +} + +class 不能相邻的节点快乐值更多 { + private class Info { + int yes; //当前节点去的快乐值 + int no; //当前节点去的快乐值 + + public Info(int yes, int no) { + this.yes = yes; + this.no = no; + } + } + + private class Employee { + public int happy; + public List nexts; + + public Employee(int h) { + happy = h; + nexts = new ArrayList<>(); + } + + } + + public Info process(Employee employee) { + if (employee == null) { + return new Info(0, 0); + } + int yes = 0; //当前节点去的快乐值 + int no = 0; //当前节点去的快乐值 + for (Employee next : employee.nexts) { + Info nextInfo = process(next); + yes += nextInfo.no; + no += Math.max(nextInfo.yes, nextInfo.no); + } + return new Info(yes, no); + } + + +} +