70. 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示:
1 <= n <= 45
当我们到达第三层楼梯时,我们有两种方法到达:从第一阶楼梯跳上去或者从第二阶楼梯跳上去
所以 f[3] = f[1] + f[2] 可以得到表达式 f[i] = f[i-1] + f[i-2]
def climbStairs(self, n: int) -> int:
f = [0] *(n+1)
f[0] = f[1] = 1
for i in range(2,n+1):
f[i] = f[i-1] + f[i-2]
return f[n]
746. 使用最小花费爬楼梯
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
总花费为 6 。
提示:
2 <= cost.length <= 1000
0 <= cost[i] <= 999
cost长度为n,而最后一个n表示向上爬需要花费的费用,所以实际上最后一层为 n 阶的顶层,所以f的长度为 n+1,求的是 n+1的值
因为可以从第0层和第1层开始爬,所以第0层和第1层 的初始值为0
当我们到达第i层时,我们可以是从第i-1层上来的,也可以是 从i-2层上来
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
f = [0] *(n+1)
for i in range(2,n+1):
f[i] = min(f[i-1]+cost[i-1],f[i-2]+cost[i-2])
return f[n]
377. 组合总和 Ⅳ
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。
题目数据保证答案符合 32 位整数范围。
示例 1: 输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。
示例 2: 输入:nums = [9], target = 3
输出:0
提示: • 1 <= nums.length <= 200 • 1 <= nums[i] <= 1000 • nums 中的所有元素 互不相同 • 1 <= target <= 1000
本题也是爬楼梯典型的题,目标为target阶阶梯,每次可以爬nums[i] 步, 0 <= i <= len(nums) -1
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
f = [0]*(target+1)
f[0] = 1
for i in range(1,target+1):
f[i] = sum([f[i-x] for x in nums if i>=x])
return f[target]
2466. 统计构造好字符串的方案数
给你整数 zero ,one ,low 和 high ,我们从空字符串开始构造一个字符串,每一步执行下面操作中的一种:
将 ‘0’ 在字符串末尾添加 zero 次。
将 ‘1’ 在字符串末尾添加 one 次。
以上操作可以执行任意次。
如果通过以上过程得到一个 长度 在 low 和 high 之间(包含上下边界)的字符串,那么这个字符串我们称为 好 字符串。
请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 109 + 7 取余 后返回。
示例 1:
输入:low = 3, high = 3, zero = 1, one = 1
输出:8
解释:
一个可能的好字符串是 "011" 。
可以这样构造得到:"" -> "0" -> "01" -> "011" 。
从 "000" 到 "111" 之间所有的二进制字符串都是好字符串。
示例 2:
输入:low = 2, high = 3, zero = 1, one = 2
输出:5
解释:好字符串为 "00" ,"11" ,"000" ,"110" 和 "011" 。
提示:
1 <= low <= high <= 105
1 <= zero, one <= low
class Solution:
def countGoodStrings(self, low: int, high: int, zero: int, one: int) -> int:
f = [0]*(high + 1)
f[0] = 1
for i in range(1,high+1):
if i >= zero and i >= one:
f[i] = f[i-zero] + f[i-one]
elif i >= zero:
f[i] = f[i-zero]
elif i >= one:
f[i] = f[i-one]
ans = sum(f[i] for i in range(low,high+1))
return ans %(10**9+7)
2266. 统计打字方案数
Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。
为了 打出 一个字母,Alice 需要 按 对应字母 i 次,i 是该字母在这个按键上所处的位置。
比方说,为了按出字母 ‘s’ ,Alice 需要按 ‘7’ 四次。类似的, Alice 需要按 ‘5’ 两次得到字母 ‘k’ 。
注意,数字 ‘0’ 和 ‘1’ 不映射到任何字母,所以 Alice 不 使用它们。
但是,由于传输的错误,Bob 没有收到 Alice 打字的字母信息,反而收到了 按键的字符串信息 。
比方说,Alice 发出的信息为 “bob” ,Bob 将收到字符串 “2266622” 。
给你一个字符串 pressedKeys ,表示 Bob 收到的字符串,请你返回 Alice 总共可能发出多少种文字信息 。
由于答案可能很大,将它对 10**9 + 7 取余 后返回。
示例 1:
输入:pressedKeys = "22233"
输出:8
解释:
Alice 可能发出的文字信息包括:
"aaadd", "abdd", "badd", "cdd", "aaae", "abe", "bae" 和 "ce" 。
由于总共有 8 种可能的信息,所以我们返回 8 。
示例 2:
输入:pressedKeys = "222222222222222222222222222222222222"
输出:82876089
解释:
总共有 2082876103 种 Alice 可能发出的文字信息。
由于我们需要将答案对 10**9 + 7 取余,所以我们返回 2082876103 % (10**9 + 7) = 82876089 。
提示:
1 <= pressedKeys.length <= 105
pressedKeys 只包含数字 '2' 到 '9' 。
本题有2个关键点:
1、求出每段相同字符的数量
2、类似于爬楼梯,如果一段字符长度为n,那么对于数字 1 2 3 4 5 6 8,相当于每次可以爬 1步/2步/3步,爬到n步时,一共有多少种爬法,如果是数字7 和 9 那么相当于每次可以爬 1步/2步/3步/4步
class Solution:
def countTexts(self, pressedKeys: str) -> int:
num_count = []
n = len(pressedKeys)
i = j = i_count = 0
while i <= n -1 and j <= n-1:
if pressedKeys[j] == pressedKeys[i]:
i_count += 1
if j == n -1:
num_count.append([pressedKeys[i],i_count])
j += 1
else:
num_count.append([pressedKeys[i],i_count])
i_count = 0
i = j
cal_list = []
for x in num_count:
s, t = x[0], x[1]
f = [0] *(t+1)
f[0] = 1
for i in range(1,t+1):
if s in ['7','9']:
f[i] = sum(f[i-m] for m in range(1,5) if i >= m)
else:
f[i] = sum(f[i-m] for m in range(1,4) if i >= m)
cal_list.append(f[t])
f_rel = 1
for i in cal_list:
f_rel = f_rel * i
return f_rel % (10**9 + 7)