From 96a39cd0db32c8fcc7a73d62795b299a1d737327 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Mon, 24 Mar 2025 18:58:37 +0800 Subject: [PATCH] =?UTF-8?q?3.24=20=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/tree/BuildTree.java | 47 ++++++++++++++++ src/main/java/tree/Flatten.java | 78 +++++++++++++++++++++++++++ src/main/java/tree/IsValidBST.java | 37 ++++++++++++- src/main/java/tree/KthSmallest.java | 27 ++++++++++ src/main/java/tree/RightSideView.java | 36 +++++++++++++ 5 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 src/main/java/tree/BuildTree.java create mode 100644 src/main/java/tree/Flatten.java create mode 100644 src/main/java/tree/KthSmallest.java create mode 100644 src/main/java/tree/RightSideView.java diff --git a/src/main/java/tree/BuildTree.java b/src/main/java/tree/BuildTree.java new file mode 100644 index 0000000..07e7a3c --- /dev/null +++ b/src/main/java/tree/BuildTree.java @@ -0,0 +1,47 @@ +package tree; + +import java.util.HashMap; +import java.util.Map; + +/** + * 题目: 105. 从前序与中序遍历序列构造二叉树 (rightSideView) + * 描述:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 + + * 链接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + + */ +//思路会 代码不会写 +public class BuildTree { + private Map indexMap; + + public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left) { + if (preorder_left > preorder_right) { + return null; + } + + // 在中序遍历中定位根节点 + int inorder_root = indexMap.get(preorder[preorder_left]); + + // 先把根节点建立出来 + TreeNode root = new TreeNode(preorder[preorder_left]); + // 得到左子树中的节点数目 + int size_left_subtree = inorder_root - inorder_left; + // 递归地构造左子树,并连接到根节点 + // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素 + root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left); + // 递归地构造右子树,并连接到根节点 + // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素 + root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1); + return root; + } + + public TreeNode buildTree(int[] preorder, int[] inorder) { + int n = preorder.length; + // 构造哈希映射,帮助我们快速定位根节点 + indexMap = new HashMap(); + for (int i = 0; i < n; i++) { + indexMap.put(inorder[i], i); + } + return myBuildTree(preorder, inorder, 0, n - 1, 0); + } +} diff --git a/src/main/java/tree/Flatten.java b/src/main/java/tree/Flatten.java new file mode 100644 index 0000000..96747d9 --- /dev/null +++ b/src/main/java/tree/Flatten.java @@ -0,0 +1,78 @@ +package tree; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +/** + * 题目: 114. 二叉树展开为链表 (rightSideView) + * 描述:给你二叉树的根结点 root ,请你将它展开为一个单链表: + * 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。 + * 展开后的单链表应该与二叉树 先序遍历 顺序相同。 + + * 链接:https://leetcode.cn/problems/flatten-binary-tree-to-linked-list/ + + */ +public class Flatten { + public void inOrderTraversal(TreeNode root,Listlist){ + if(root!=null) { + list.add(root); + inOrderTraversal(root.left, list); + inOrderTraversal(root.right, list); + } + } + //O(N)空间复杂度 递归前序 + public void flatten(TreeNode root) { + Listlist=new ArrayList<>(); + TreeNode head=new TreeNode(0); + TreeNode tp=head; + inOrderTraversal(root,list); + for (TreeNode treeNode : list) { + tp.left=null; + tp.right=treeNode; + tp=tp.right; + } + } + //迭代前序遍历也要回 + public void flatten1(TreeNode root) { + if (root == null) { + return; + } + Deque stack = new LinkedList(); + stack.push(root); + TreeNode prev = null; + while (!stack.isEmpty()) { + TreeNode curr = stack.pop(); + if (prev != null) { + prev.left = null; + prev.right = curr; + } + TreeNode left = curr.left, right = curr.right; + if (right != null) { + stack.push(right); + } + if (left != null) { + stack.push(left); + } + prev = curr; + } + } + //O(1)空间 + public void flatten2(TreeNode root) { + TreeNode curr = root; + while (curr != null) { + if (curr.left != null) { + TreeNode next = curr.left; + TreeNode predecessor = next; + while (predecessor.right != null) { + predecessor = predecessor.right; + } + predecessor.right = curr.right; + curr.left = null; + curr.right = next; + } + curr = curr.right; + } + } +} diff --git a/src/main/java/tree/IsValidBST.java b/src/main/java/tree/IsValidBST.java index 7e99ad0..eee5b4a 100644 --- a/src/main/java/tree/IsValidBST.java +++ b/src/main/java/tree/IsValidBST.java @@ -1,4 +1,9 @@ package tree; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * 题目: 98. 验证二叉搜索树 (isValidBST) * 描述:给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 @@ -11,7 +16,37 @@ package tree; */ public class IsValidBST { + //递归 + public boolean helper(TreeNode node, long lower, long upper) { + if (node == null) { + return true; + } + if (node.val <= lower || node.val >= upper) { + return false; + } + return helper(node.left, lower, node.val) && helper(node.right, node.val, upper); + } + public boolean isValidBST2(TreeNode root) { + return helper(root, Long.MIN_VALUE, Long.MAX_VALUE); + } + + //中序遍历 + public void dfs(TreeNode root,Listlist){ + if(root!=null){ + dfs(root.left,list); + list.add(root.val); + dfs(root.right,list); + } + } public boolean isValidBST(TreeNode root) { - return false; + List list = new ArrayList<>(); + dfs(root, list); + // 检查中序遍历结果是否严格递增 + for (int i = 1; i < list.size(); i++) { + if (list.get(i) <= list.get(i - 1)) { + return false; + } + } + return true; } } diff --git a/src/main/java/tree/KthSmallest.java b/src/main/java/tree/KthSmallest.java new file mode 100644 index 0000000..6216a4d --- /dev/null +++ b/src/main/java/tree/KthSmallest.java @@ -0,0 +1,27 @@ +package tree; + +import java.util.ArrayList; +import java.util.List; + +/** + * 题目: 230. 二叉搜索树中第 K 小的元素 (sortedArrayToBST) + * 描述:给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。 + + * 链接:https://leetcode.cn/problems/kth-smallest-element-in-a-bst/ + + */ +public class KthSmallest { + //中序遍历 + public void dfs(TreeNode root, List list){ + if(root!=null){ + dfs(root.left,list); + list.add(root.val); + dfs(root.right,list); + } + } + public int kthSmallest(TreeNode root, int k) { + Listlist=new ArrayList<>(); + dfs(root,list); + return list.get(k-1); + } +} diff --git a/src/main/java/tree/RightSideView.java b/src/main/java/tree/RightSideView.java new file mode 100644 index 0000000..45da171 --- /dev/null +++ b/src/main/java/tree/RightSideView.java @@ -0,0 +1,36 @@ +package tree; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * 题目: 199. 二叉树的右视图 (rightSideView) + * 描述:给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 + + * 链接:https://leetcode.cn/problems/binary-tree-right-side-view/description/ + + */ +public class RightSideView { + public List rightSideView(TreeNode root) { + Queuequeue=new ArrayDeque<>(); + Listres=new ArrayList<>(); + if(root==null) + return res; + queue.offer(root); + while (!queue.isEmpty()){ + int size=queue.size(); + for (int i = 0; i < size; i++) { + TreeNode temp=queue.poll(); + if(i==size-1) + res.add(temp.val); + if(temp.left!=null) + queue.offer(temp.left); + if(temp.right!=null) + queue.offer(temp.right); + } + } + return res; + } +}