783. 二叉搜索树节点最小距离
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
思路
因为是二叉搜索数,所以根结点一定是中间值,最小距离是左结点和根节点的差值,或者有结点和根节点的差值。
int ans;
TreeNode pre = null;
public int minDiffInBST(TreeNode root) {
ans = Integer.MAX_VALUE;
midSearch(root);
return ans;
}
public void midSearch(TreeNode root) {
if(root == null) {
return;
}
midSearch(root.left);
if(pre != null) {
ans = Math.min(ans, root.val - pre.val);
}
pre = root;
midSearch(root.right);
}
213. 打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
思路
这个比之前那个题难
问题就在于最后的数和第一个数是在一起的
那么怎么隔离?
题解给的这个方法真的好,那就分开计算。
第一种是只有第一个数参与的dp
第二种是只有第二个数参与的dp
求最后的最大值即可
完整代码
public int rob(int[] nums) {
int n = nums.length;
if(n == 0){
return 0;
}
if(n == 1){
return nums[0];
}
if(n == 2){
return Math.max(nums[0], nums[1]);
}
int[] dp1 = new int[n - 1];
int[] dp2 = new int[n - 1];
dp1[0] = nums[0];
dp1[1] = Math.max(nums[0], nums[1]);
dp2[0] = nums[1];
dp2[1] = Math.max(nums[2], nums[1]);
for(int i = 2; i < n; i++){
if(2 <= i && i <= n - 2){
dp1[i] = Math.max(dp1[i - 1], nums[i] + dp1[i - 2]);
}
if(3 <= i && i <= n - 1){
dp2[i - 1] = Math.max(dp2[i - 2], nums[i] + dp2[i - 3]);
}
}
return Math.max(dp1[n - 2], dp2[n - 2]);
}
105. 从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
思路
二叉树的构造这个题还是很基础的
一般用到二叉树就要用到递归
完整代码
public TreeNode buildTree(int[] preorder, int[] inorder) {
return bulidTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
public TreeNode bulidTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end){
if(p_start == p_end){
return null;
}
TreeNode root = new TreeNode(preorder[p_start]);//前序遍历的开始就是根节点
int i_root = 0;
for(int i = i_start; i < i_end; i++){//找到根节点在中序遍历的位置
if(inorder[i] == root.val){
i_root = i;
break;
}
}
int left = i_root - i_start;
root.left = bulidTreeHelper(preorder, p_start + 1, p_start + left + 1, inorder, i_start, i_root);//找到左子树在两个数组中的起始
root.right = bulidTreeHelper(preorder, p_start + left + 1, p_end, inorder, i_root + 1, i_end);//找到右子树在两个数组中的起始
return root;
}