学习目标:
60天训练营打卡计划!
耶耶耶耶!已经过了1/3啦!
栈用于模拟递归调用的状态,实现深度优先遍历,而队列用于按层级顺序遍历,实现广度优先遍历。
学习内容:
654.最大二叉树
- 使用递归法,思路比较清晰。
- 一定要认真看明白题目的要求,再根据题目构造就会变得很清晰。
class Solution {
// 获取子数组中的最大值的位置
private int getMax(int[] nums, int start, int end) {
int index = start;
int max = nums[start];
for(int i = start; i < end; i++){
if(nums[i] > max){
max = nums[i];
index = i;
}
}
return index;
}
private TreeNode constructHelper(int[] nums, int start, int end) {
if(end == 0 || end - start == 0) return null;
int max_index = getMax(nums, start, end);
TreeNode root = new TreeNode(nums[max_index]);
if(end - start == 1) return root;
// 构造左子树
if(start < max_index)
root.left = constructHelper(nums, start, max_index);
// 构造右子树
if(end - 1 > max_index)
root.right = constructHelper(nums, max_index + 1, end);
return root;
}
public TreeNode constructMaximumBinaryTree(int[] nums) {
return constructHelper(nums, 0, nums.length);
}
}
617.合并二叉树
- 一起操作两个二叉树(n1 n2)
-
- 结束条件是:当n1为空时,返回n2;同理。
处理过程:两个节点都有值时,相加并存储(中)。
对于左右子节点则直接递归函数。
- 结束条件是:当n1为空时,返回n2;同理。
- 迭代法:
-
- 最重要的思想—不需要新建一棵树,在原有的树的基础上进行操作即可,因为que队列只是存了二叉树节点的引用,并不会破坏原有的二叉树的结构。
-
- 迭代法通过循环和条件判断来逐个处理数据结构中的元素
- 递归法:
-
- 可以新建树,也可以在原树的基础上继续操作。
难点是如何同时操作两个树?或者说同时操作两棵树表现在什么地方?
- 可以新建树,也可以在原树的基础上继续操作。
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
Queue<TreeNode> que = new LinkedList<>();
int size = -1;
if(root1 == null && root2 == null) return null;
if(root1 == null && root2 != null) return root2;
if(root1 != null && root2 == null) return root1;
que.add(root1);
que.add(root2);
while(!que.isEmpty()){
TreeNode node1 = que.remove();
TreeNode node2 = que.remove();
// add()函数存的是引用值,所以修改node1其实就是在修改root1
// 共有的部分因为要做求和操作,故要加入队列。
node1.val += node2.val;
if(node1.left != null && node2.left != null){
que.add(node1.left);
que.add(node2.left);
}
if(node1.right != null && node2.right != null){
que.add(node1.right);
que.add(node2.right);
}
// 直接将root2中的子树继承
if(node1.left == null && node2.left != null)
node1.left = node2.left;
if(node1.right == null && node2.right != null)
node1.right = node2.right;
}
return root1;
}
}
// 递归
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
// 结束条件
if(root1 == null) return root2;
if(root2 == null) return root1;
root1.val += root2.val;
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
return root1;
}
}
700.二叉搜索树中的搜索
- 迭代法:借助二叉搜索树的搜索规则,使得迭代法变得异常的简单。
- 递归法:结束条件有两个,只需要对左右子树操作即可。
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while(root != null){
if(root.val > val) root = root.left;
else if(root.val < val) root = root.right;
else return root;
}
return root;
}
}
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
TreeNode node = new TreeNode(0);
if(root == null || val == root.val) return root;
if(val < root.val) node = searchBST(root.left, val);
if(val > root.val) node = searchBST(root.right, val);
return node;
}
}
98.验证二叉搜索树
- 递归法:使用中序遍历,对于二叉搜索树来说,中序遍历得到的结果是有顺序的。
class Solution {
// 如果放到递归里,每次的节点都会和-Integer.MAX_VALUE做对比,那么一定是true
private long max = -Long.MAX_VALUE;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
// 使用中序遍历
boolean left = isValidBST(root.left);
if(root.val <= max) return false;
max = root.val;
boolean right = isValidBST(root.right);
return right && left;
}
}
class Solution {
// 如果放到递归里,每次的节点都会和-Integer.MAX_VALUE做对比,那么一定是true
// private long max = -Long.MAX_VALUE;
// 双指针法
TreeNode pre = null;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
// 使用中序遍历
boolean left = isValidBST(root.left);
if(pre != null && pre.val >= root.val) return false;
pre = root;
boolean right = isValidBST(root.right);
return right && left;
}
}
学习时间:
- 上午一小时,下午两个小时,整理文档半小时。
- 2024.2.21 二刷