算法日记day 8(爬楼梯|四数相加)

一、爬楼梯

题目:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

思路:

采用动态规划的思想

当n=1时,有一种方法

当n=2时,有两种方法,即1和2

当n=3时,有三种方法,即1+1+1,1+2,2+1

当n=4时,有五种方法,即1+1+1+1,1+1+2,1+2+1,2+1+1,2+2

.............

由此可以总结出一个递推式,f(n) = f(n-1) + f(n-2)

可以发现,爬楼梯问题演变成个斐波那契数列的问题,代码就很好写了

public int climbStairs(int n) {
    int[] dp = new int[n + 1];  // 创建一个数组 dp,长度为 n + 1,用于存储不同台阶数对应的方法数
    dp[0] = 1;  // 0 阶楼梯,只有一种方法:不爬
    dp[1] = 1;  // 1 阶楼梯,只有一种方法:爬一步到顶
    
    // 循环计算从 2 阶到 n 阶的方法数
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];  // 当前台阶数的方法数等于前一阶和前两阶方法数之和
    }
    
    return dp[n];  // 返回爬到 n 阶的方法数
}

具体分析:

  1. 数组定义与初始化

    • int[] dp = new int[n + 1]; 创建一个长度为 n + 1 的整数数组 dp,用来存储到达每个台阶的不同方法数。数组下标表示台阶数,数组值表示到达该台阶的方法数。
  2. 初始条件

    • dp[0] = 1; 0 阶楼梯只有一种方法,即不爬。
    • dp[1] = 1; 1 阶楼梯只有一种方法,即爬一步到顶。
  3. 动态规划转移方程

    • for (int i = 2; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; }
      • 从 2 阶开始循环到 n 阶,计算每个台阶的方法数。
      • dp[i] = dp[i - 1] + dp[i - 2];:当前台阶 i 的方法数等于到达前一阶和前两阶的方法数之和。这是因为到达当前台阶可以从前一阶爬一步到达,或者从前两阶爬两步到达。
  4. 返回结果

    • return dp[n]; 返回存储在 dp 数组中的到达第 n 阶楼梯的方法数,即解决问题的答案。

二、四数相加

题目:

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

思路:

本题采用哈希表的方法,优先判断nums1+nums2中的值,再判断num3+nums4中的值,如果前者的值为i+j,后者的值为-(i+j),说明四个数组相加的值等于0

代码:

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
    int res = 0; // 用于存储满足条件的组合数量
    Map<Integer, Integer> map = new HashMap<>(); // 创建一个 HashMap,用于存储两个数组元素之和及其出现次数

    // 第一对循环,统计 nums1 和 nums2 中元素的和及其出现次数
    for (int i : nums1) {
        for (int j : nums2) {
            int sum = i + j; // 计算当前两个元素之和
            map.put(sum, map.getOrDefault(sum, 0) + 1); // 将该和作为 key,出现次数作为 value 放入 map 中
        }
    }

    // 第二对循环,统计 nums3 和 nums4 中元素的和,在 map 中查找是否存在相加为 0 的情况,并累加结果到 res 中
    for (int i : nums3) {
        for (int j : nums4) {
            res += map.getOrDefault(0 - i - j, 0); // 查找 map 中是否有 -(i+j) 的键,并将其值累加到 res 中
        }
    }

    return res; // 返回满足条件的组合数量
}

具体解释:

  1. 初始化变量

    • res:用于记录满足条件的四数之和为 0 的组合数量。
    • map:用于存储两个数组中元素之和及其出现次数的 HashMap。
  2. 第一对循环(外层循环):

    • 遍历 nums1 中的每一个元素 i 和 nums2 中的每一个元素 j
    • 计算当前两个元素的和 sum = i + j
    • 将 sum 作为 key,将其在 map 中的出现次数增加 1。
  3. 第二对循环(内层循环):

    • 遍历 nums3 中的每一个元素 i 和 nums4 中的每一个元素 j
    • 计算当前两个元素的和 -i - j
    • 使用 map.getOrDefault(0 - i - j, 0) 查找 map 中是否有 -i - j 这个 key,如果有,则将其对应的值累加到 res 中。
  4. 返回结果

    • 返回 res,即满足四数之和为 0 的组合数量。

拓展:

map.getOrDefault(key, defaultValue) 是 Java 中用于获取 Map 中指定 key 对应的值的方法。如果 Map 中包含指定的 key,则返回与该 key 关联的值;如果 Map 中不包含指定的 key,则返回 defaultValue。

参数解释:

  • key:要在 Map 中查找的键。
  • defaultValue:如果 Map 中不包含指定的 key,则返回的默认值。

使用示例:

假设有一个 Map map,其中包含一些键值对:

Map<String, Integer> map = new HashMap<>();
map.put("apple", 10);
map.put("banana", 20);
map.put("cherry", 30);

 现在我们可以使用 getOrDefault 方法来获取指定键的值:

int count1 = map.getOrDefault("apple", 0); // 此时 count1 = 10
int count2 = map.getOrDefault("grape", 0); // 此时 count2 = 0,因为 "grape" 不在 Map 中,返回 defaultValue = 0

 在上面的例子中:

  • map.getOrDefault("apple", 0) 返回键 "apple" 对应的值 10。
  • map.getOrDefault("grape", 0) 返回键 "grape" 对应的默认值 0,因为 "grape" 在 Map 中不存在。

适用场景:

getOrDefault 方法通常在需要从 Map 获取值时使用,尤其是在不确定键是否存在时,可以提供一个默认值,避免因为键不存在而引发异常或返回 null 的情况。

 今天的学习就到这里了

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值