2021-04-16刷题记录

这篇博客探讨了如何在二叉搜索树中找到节点间的最小差值,并使用动态规划解决打家劫舍问题。在二叉搜索树问题中,通过中序遍历找到最小差值;而在动态规划的打家劫舍问题中,通过分治策略计算最大盗窃金额。代码示例展示了具体的实现方法。
摘要由CSDN通过智能技术生成

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;

    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值