This commit is contained in:
zhangsan 2025-03-24 18:58:37 +08:00
parent 0d237e047c
commit 96a39cd0db
5 changed files with 224 additions and 1 deletions

View File

@ -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<Integer, Integer> 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<Integer, Integer>();
for (int i = 0; i < n; i++) {
indexMap.put(inorder[i], i);
}
return myBuildTree(preorder, inorder, 0, n - 1, 0);
}
}

View File

@ -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,List<TreeNode>list){
if(root!=null) {
list.add(root);
inOrderTraversal(root.left, list);
inOrderTraversal(root.right, list);
}
}
//O(N)空间复杂度 递归前序
public void flatten(TreeNode root) {
List<TreeNode>list=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<TreeNode> stack = new LinkedList<TreeNode>();
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;
}
}
}

View File

@ -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,List<Integer>list){
if(root!=null){
dfs(root.left,list);
list.add(root.val);
dfs(root.right,list);
}
}
public boolean isValidBST(TreeNode root) {
return false;
List<Integer> 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;
}
}

View File

@ -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<Integer> list){
if(root!=null){
dfs(root.left,list);
list.add(root.val);
dfs(root.right,list);
}
}
public int kthSmallest(TreeNode root, int k) {
List<Integer>list=new ArrayList<>();
dfs(root,list);
return list.get(k-1);
}
}

View File

@ -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<Integer> rightSideView(TreeNode root) {
Queue<TreeNode>queue=new ArrayDeque<>();
List<Integer>res=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;
}
}