LeetCode 热题 100 | 动态规划(一)

news/2025/2/14 4:06:27/

目录

1  70. 爬楼梯

1.1  基本思路

1.2  官方题解

2  118. 杨辉三角

3  198. 打家劫舍


菜鸟做题,语言是 C++

1  70. 爬楼梯

核心思想:把总问题拆解为若干子问题。

  • 总问题:上到 5 楼的方式有多少种
  • 子问题:上到 4 楼的方式有多少种、上到 3 楼的方式有多少种
  • 总问题 = 子问题 1 + 子问题 2

因为题目要求每次只能爬 1 或 2 个台阶,所以子问题只有两个。

1.1  基本思路

假设按照英国算法要爬 6 层楼,如下图所示:

使用一个名为 dp 的数组来存储爬到每一层楼的方式种数。

由于我们只能从 4 或 3 楼爬到 5 楼,因此爬到 5 楼的方式种数 = 爬到 4 楼的方式种数 + 爬到 3 楼的方式种数,即 dp[5] = dp[4] + dp[3],以此类推。

特别地,对于 0 楼和 1 楼,由于只有一种方式爬到它们,因此直接设为 1 即可。

很不幸,上述方法需要维护一个长为 n 的数组 dp,因此空间复杂度是 O(n),而这样会超出内存限制,下面来看官方题解的奇妙方法。

1.2  官方题解

由 1.1 节的分析可知,dp[5] 只与 dp[4] 和 dp[3] 有关。因此在第 5 时刻,我们只需要记住 dp[4] 和 dp[3] 即可。换句话说,就是通过忘记其他 dp 元素来节省内存空间。

如下图所示。我们设置变量 p、q、r 来分别存储 dp[i - 2]、dp[i - 1]、dp[i],并不断更新这些变量。

可以把 p、q、r 理解为一个滑动窗口,每次同时向后移动一格,以此忘记不再需要的 dp 元素。 

完整代码如下:

class Solution {
public:int climbStairs(int n) {int p = 0, q = 0, r = 1;for (int i = 0; i < n; ++i) {p = q;q = r;r = p + q;}return r;}
};

这个启动方式还是挺妙的:

int p = 0, q = 0, r = 1;

2  118. 杨辉三角

核心思想:把总问题拆解为若干子问题。

  • 总问题:第 i 行第 j 列元素的值
  • 子问题:第 i - 1 行第 j 列元素的值、第 i - 1 行第 j + 1 列元素的值
  • 总问题 = 子问题 1 + 子问题 2

模仿上述动图初始化 ans 数组:

vector<vector<int>> ans(numRows);
for (int i = 1; i <= numRows; ++i) {ans[i - 1].resize(i);ans[i - 1][0] = 1;ans[i - 1][i - 1] = 1;
}

就是把那一圈 “1” 先填了,虽然笨,但貌似不影响效率。

完整代码如下:

class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>> ans(numRows);for (int i = 1; i <= numRows; ++i) {ans[i - 1].resize(i);ans[i - 1][0] = 1;ans[i - 1][i - 1] = 1;}for (int i = 2; i < numRows; ++i) {for (int j = 1; j < ans[i].size() - 1; ++j) {ans[i][j] = ans[i - 1][j - 1] + ans[i - 1][j];}}return ans;}
};

3  198. 打家劫舍

核心思想:把总问题拆解为若干子问题。

  • 总问题:打劫完第 i 家所获最大金额
  • 子问题:打劫完第 i - 2 家所获最大金额、打劫完第 i - 3 家所获最大金额
  • 总问题 = 子问题 1 + 子问题 2

Q:为什么只考虑打劫第 i - 2 家和第 i - 3 家?

A:假设 i = 5,如下图所示。对于第 i - 1 家,由于不能打劫相邻的两家,因此要想打劫第 i 家,就不能打劫第 i - 1 家。可以打劫第 i - 2 家或者第 i - 3 家,如情况一和情况二所示。对于第 i - 4 家,由于要使金额最大,因此肯定还会打劫第 i - 2 家,从而认为情况一等价于情况三。

综上,我们只需要考虑情况一和情况二即可。

同  70. 爬楼梯  的简化思路相同,我们同样可以只设置几个变量来存储历史打劫金额,而非使用一个 dp 数组。其中,h3 存储第 i - 3 家,h2 存储第 i - 2 家,h1 存储第 i - 1 家,h0 存储第 i 家。

完整代码如下:

class Solution {
public:int rob(vector<int>& nums) {int h3 = 0, h2 = 0, h1 = 0;int ans = INT_MIN;for (int i = 0; i < nums.size(); ++i) {int h0 = max(nums[i] + h3, nums[i] + h2);ans  = max(ans, h0);h3 = h2;h2 = h1;h1 = h0;}return ans;}
};


http://www.ppmy.cn/news/1404556.html

相关文章

CSS面试题---基础

1、css选择器及优先级 选择器优先级&#xff1a;内联样式>id选择器>类选择器、属性选择器、伪类选择器>标签选择器、微元素选择器 注意&#xff1a; !important优先级最高&#xff1b; 如果优先级相同&#xff0c;则最后出现的样式生效&#xff1b; 继承得到的样式优先…

网络钓鱼升级 Darcula如何窃取用户信息

近日&#xff0c;网络安全领域一种名为 “Darcula” 的网络钓鱼欺诈&#xff08;PhaaS&#xff09;悄然兴起。这种新型钓鱼方式不同于传统的手段&#xff0c;它巧妙地利用了谷歌信息和 iMessage 的富通信服务&#xff08;RCS&#xff09;&#xff0c;成为了网络犯罪分子的新手段…

考研数学|《1800》+《660》精华搭配混合用(经验分享)

肯定不行&#xff0c;考研数学哪有这么容易的&#xff01; 先说说这两本习题册&#xff0c;李永乐老师推出的新版660题&#xff0c;相较于18年前的版本&#xff0c;难度略有降低&#xff0c;更加适合初学者。因此&#xff0c;对于处于基础阶段的学习者来说&#xff0c;新版660…

Windows中Microsoft Edge兼容性问题修复方案

针对Microsoft Edge浏览器在Windows系统中出现的兼容性问题解决步骤和策略&#xff1a; 作者是更改了注册表解决的&#xff0c;问题不一&#xff0c;大家遇到兼容性问题先按照第7个情况进行设置&#xff0c;大部分人是这个情况&#xff01; 清理缓存和Cookies 按快捷键:ctrlshi…

Qt + VS2017 创建一个简单的图片加载应用程序

简介&#xff1a; 本文介绍了如何使用Qt创建一个简单的图片加载应用程序。该应用程序可以打开图片文件并在界面上显示选定的图片&#xff0c;并保存用户上次选择的图片路径。 1. 创建项目&#xff1a; 首先&#xff0c;在VS中创建一个新的Qt Widgets应用程序项目&#xff0c;并…

Windows 11 专业版 23H2 Docker Desktop 下载 安装 配置 使用

博文目录 文章目录 Docker Desktop准备系统要求 (WSL 2 backend)在 Windows 上打开 WSL 2 功能先决条件开启 WSL 2 WSL下载安装启动配置使用镜像 Image卷积 Volumes容器 Containers 命令RedisMySQLPostGreSQL Docker Desktop Overview of Docker Desktop Docker Desktop 疑难解…

刷LeetCode:冒泡排序详解 【2/1000 第二题】含imagemagick动态效果图

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

【蓝桥杯第十四届省赛B】(部分详解)

【01串的熵】 https://www.lanqiao.cn/problems/3498/learning/?subject_code1&group_code4&match_num14&match_flow1&origincup #include <iostream> #include<cmath> using namespace std; int main() {double n23333333;double sum0;for(int…