leetcode刷题记录day017:70和278

70、难度简单:

题意:一个楼梯有 n 个台阶,你的每一步有两种选择,一次性跨2个台阶或1个台阶。求有多少种不同方法爬完楼梯。
注意:给定 n 是一个正整数,非0非负

方法一:数学

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0HfBwb70-1633343326142)(70. 爬楼梯.assets/image-20211004155837850.png)]

class Solution {
    public int climbStairs(int n) {
        double sqrt_5 = Math.sqrt(5);
        double fib_n = Math.pow((1 + sqrt_5) / 2, n + 1) - Math.pow((1 - sqrt_5) / 2,n + 1);
        return (int)(fib_n / sqrt_5);
    }
}

裴波那契数列:斐波那契数列指的是这样一个数列:
在这里插入图片描述

这个数列从第3项开始,每一项都等于前两项之和
上述图中的公式就是求解第n项值为何的公式,此公式前提:
在这里插入图片描述

结合这道题:楼梯总阶数n对应裴波那契数列的第n+1项的n+1,而一共的通过方法对应该项的数值

原理:

当总阶数为1时,对应裴波那契第1+1=2项数值为1,即方法只有一种就是跨一步
当总阶数为2时,对应第2+1=3项值为2,即方法有两种,跨两个1步或跨一个2步
前两项恰好满足本题要求
拿4层台阶举例子。首先考虑怎么下第一脚,一步还是两步:
一步:剩下三步。那么剩下的三步能怎么走,也是按之前走出来的三步怎么走来进行;
两步:剩下两步。那么剩下的两步能怎么走,也是按之前走出来的两步怎么走来进行;
f(4) = f(3) + f(2)
剩下的同理

方法二:动态规划:
class Solution {
    public int climbStairs(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

本问题其实常规解法可以分成多个子问题,爬第 n 阶楼梯的方法数量,等于 2 部分之和:
(1)爬上 n-1 阶楼梯的方法数量。因为再爬 1 阶就能到第 n 阶
(2)爬上 n-2 阶楼梯的方法数量,因为再爬 2 阶就能到第 n 阶
在这里插入图片描述

278、难度简单:

题意:题传入参数 n (代表1、2、3、…、n),然后我们通过调用题目帮我们写好的方法bool isBadVersion(version)来判断这 n 个数中哪些是错误的。我们需要找出第一个(最早出现的)错误的版本。

要求:尽量减少对调用 API(isBadVersion方法) 的次数

方法一:二分查找
/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1, right = n;
        while (left < right) { // 循环直至区间左右端点相同
            int mid = left + (right - left) / 2; // ※ 防止计算时溢出
            if (isBadVersion(mid)) {
                right = mid; // 答案在区间 [left, mid] 中
            } else {
                left = mid + 1; // 答案在区间 [mid+1, right] 中
            }
        }
        // 此时有 left == right,区间缩为一个点,即为答案
        return left;
    }
}

原理:两个指针 left 和 right,先求出它们的中间值 mid,若为错误的那就将 right 赋值为 mid,否则将 left 赋值为 mid。
也就是区间的左右两点都是错误的版本,并且一旦确认为错误后就不会改变除非存在更靠内侧的错误版本。
最终两点归一就是所求值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeYello

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值