2022-12-26 leetcode与蓝桥刷题情况

一、leetcode题目

1.打家劫舍 III

题目描述
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
在这里插入图片描述

2.测试用例

输入:

[3,2,3,null,3,null,1]

输出:

7

解释:

小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7

提示

  • 树的节点数在 [ 1 , 1 0 4 ] [1, 10^4] [1,104] 范围内
  • 0 < = N o d e . v a l < = 1 0 4 0 <= Node.val <= 10^4 0<=Node.val<=104

3.思路

这个题目是我刻意挑的,学习一下树形dp,之前没有接触树形dp的题目。当前阶段的值可由上一阶段推导而来。但每个阶段可由两种状态偷当前房屋不偷当前房屋。两种状态都需要保存。

  • 偷取当前房屋能够取得的最大价值: v a l = l e f t d p [ 0 ] ( 不偷左孩子房屋的价值 ) + r i g h t d p [ 0 ] ( 不偷右孩子房屋的价值 ) + c u r . v a l ( 当前房屋的价值 ) val = leftdp[0](不偷左孩子房屋的价值)+rightdp[0](不偷右孩子房屋的价值)+cur.val(当前房屋的价值) val=leftdp[0](不偷左孩子房屋的价值)+rightdp[0](不偷右孩子房屋的价值)+cur.val(当前房屋的价值)
  • 不偷取当前房屋能够取得的最大价值: v a l = m a x ( l e f t d p [ 0 ] , l e f t d p [ 1 ] ) + m a x ( r i g h t d p [ 0 ] + r i g h t d p [ 1 ] ) ( 左右孩子偷与不偷的最大值之和 ) val=max(leftdp[0],leftdp[1]) + max(rightdp[0] + rightdp[1])(左右孩子偷与不偷的最大值之和) val=max(leftdp[0],leftdp[1])+max(rightdp[0]+rightdp[1])(左右孩子偷与不偷的最大值之和)

4.算法实现

class Solution {
    public int rob(TreeNode root) {
        int[] res = dfs(root);
        return Math.max(res[0], res[1]);
    }

    private int[] dfs(TreeNode node){
        if(node == null) return new int[]{0, 0};
        int[] leftdp = dfs(node.left);
        int[] rightdp = dfs(node.right);
        int val1 = node.val + leftdp[0] + rightdp[0];
        int val2 = Math.max(leftdp[0], leftdp[1]) + Math.max(rightdp[0], rightdp[1]);
        return new int[]{val2, val1};
    }
}

二、蓝桥题目

1.砝码称重

题目描述
你有一架天平和 N N N 个砝码,这 N N N 个砝码重量依次是 W 1 , W 2 , ⋅ ⋅ ⋅ , W N W_1, W_2, · · · , W_N W1,W2,⋅⋅⋅,WN

请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。
输入描述
输入的第一行包含一个整数 NN。

第二行包含 N N N 个整数: W 1 , W 2 , W 3 , ⋅ ⋅ ⋅ , W N W_1, W_2, W_3, · · · , W_N W1,W2,W3,⋅⋅⋅,WN

输出描述
输出一个整数代表答案。

2.测试用例

输入:

3
1 4 6

输出:

10

3.思路

每个砝码可以有两种状态,放在天平左边(-),放在天平右边(+)。
使用一个set存放所有可能性,再使用一个set存放能组成的正整数合计。最终结果为存放正整数set的长度。

4.算法实现

import java.util.Scanner;
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int n = scan.nextInt();
        HashSet<Integer> set = new HashSet<>();
        HashSet<Integer> res = new HashSet<>();
        for(int i = 0; i < n; i++){
          int cur = scan.nextInt();
          res.add(cur);
          
          for(int k = 0; k < 2; k++){
            cur = -cur;
            List<Integer> list = new ArrayList<>(set);
            for(int num : list){
              int a = num + cur;
              set.add(a);
              if(a > 0) res.add(a);
            }
          }
          set.add(cur);
          set.add(-cur);
        }
        System.out.println(res.size());
        scan.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值