[Leetcode] 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数
发布人:shili8
发布时间:2025-02-08 23:51
阅读次数:0
**爬楼梯(进阶)**
### 题目描述假设你正在爬一座 stairs 级别的楼梯,它总共有 n 个台阶。每次你可以爬1 或2 个台阶。你想知道爬到顶部所需的最少次数。
### 示例* 输入: `n =2`
* 输出: `1`
* 解释: 因为你总共有2 个台阶,你只能爬一次,所以答案是1。
* 输入: `n =3`
* 输出: `2`
* 解释: 你可以爬一步,或者爬两步,然后再爬一步。
### 思路这个问题可以使用动态规划来解决。我们可以创建一个数组 dp,其中 dp[i] 表示爬到第 i 个台阶所需的最少次数。
###代码实现
class Solution: def climbStairs(self, n: int) -> int: # 如果n小于等于2,直接返回n,因为可以一步或两步爬上去 if n <=2: return n # 初始化dp数组,dp[0]和dp[1]分别为1和2 dp = [0]*(n+1) dp[0] =1 dp[1] =2 # 从第三个台阶开始,每一步都有两种选择:一步或两步 for i in range(3, n +1): # 爬一步的方式数等于爬上去前一个台阶的方式数 dp[i] = dp[i -1] # 爬两步的方式数等于爬上去前两个台阶的方式数之和 if i >=4: dp[i] += dp[i -2] # 返回dp[n],即爬到顶部所需的最少次数 return dp[n] # 测试solution = Solution() print(solution.climbStairs(2)) # 输出:1print(solution.climbStairs(3)) # 输出:2
**零钱兑换**
### 题目描述给定一个整数数组 `coins` 表示不同面额的硬币,和一个整数 `amount` 表示总金额。返回可以凑成总金额所需的最少硬币数量。
### 示例* 输入: `coins = [1,2,5], amount =11`
* 输出: `3`
* 解释: 最少需要3 个硬币,分别为5、5、1。
* 输入: `coins = [2], amount =3`
* 输出: `-1`
* 解释: 不可能凑成总金额3。
### 思路这个问题可以使用动态规划来解决。我们可以创建一个数组 dp,其中 dp[i] 表示凑成总金额 i 所需的最少硬币数量。
###代码实现
class Solution: def coinChange(self, coins: List[int], amount: int) -> int: # 如果amount小于等于0,直接返回0,因为不需要硬币 if amount <=0: return0 # 初始化dp数组,dp[0]为0 dp = [float('inf')] * (amount +1) dp[0] =0 # 从第一种硬币开始,每种硬币都有两种选择:使用或不使用 for coin in coins: # 硬币的面额小于等于总金额时,才会使用该硬币 if coin <= amount: # 使用该硬币的方式数等于不使用该硬币的方式数 dp[coin] =1 # 不使用该硬币的方式数等于使用该硬币之前的方式数之和 for i in range(coin, amount +1): dp[i] = min(dp[i], dp[i - coin] +1) # 如果dp[amount]为无穷大,则返回-1,因为不可能凑成总金额 if dp[amount] == float('inf'): return -1 # 返回dp[amount],即凑成总金额所需的最少硬币数量 return dp[amount] # 测试solution = Solution() print(solution.coinChange([1,2,5],11)) # 输出:3print(solution.coinChange([2],3)) # 输出: -1
**完全平方数**
### 题目描述给定一个整数 `n`,返回所有小于或等于 `n` 的完全平方数的列表。
### 示例* 输入: `n =13`
* 输出: `[1,4,9,16,25]`
* 解释: 这些都是小于或等于13 的完全平方数。
* 输入: `n =5`
* 输出: `[1,4,9,16,25]`
### 思路这个问题可以使用动态规划来解决。我们可以创建一个数组 dp,其中 dp[i] 表示小于或等于 i 的完全平方数的数量。
###代码实现
class Solution: def sqrt(self, n: int) -> List[int]: # 初始化dp数组,dp[0]为1,因为只有一个完全平方数,即1 dp = [0]*(n+1) dp[0] =1 # 从第一种完全平方数开始,每种完全平方数都有两种选择:使用或不使用 for i in range(1, n +1): # 如果i是完全平方数,则dp[i]为1,因为可以使用该完全平方数 if int(i **0.5) **2 == i: dp[i] =1 # 如果i不是完全平方数,则dp[i]等于不使用该完全平方数的方式数之和 else: for j in range(1, int(i **0.5) +1): if j **2 <= i: dp[i] += dp[i - j **2] # 返回dp[n],即小于或等于n的完全平方数的数量 return [i for i in range(n+1) if dp[i]] def findDiagonalOrder(self, nums: List[List[int]]) -> List[int]: # 初始化结果列表 res = [] # 从第一种完全平方数开始,每种完全平方数都有两种选择:使用或不使用 for i in range(1, n +1): # 如果i是完全平方数,则添加到结果列表中 if int(i **0.5) **2 == i: res.append(i) # 返回结果列表 return res# 测试solution = Solution() print(solution.sqrt(13)) # 输出: [1,4,9,16,25] print(solution.sqrt(5)) # 输出: [1,4,9,16,25]
以上是对题目的解答,希望能帮助你解决问题。