力扣刷题44-46(力扣0062/0152/0198)

news2024/9/21 22:52:26

62. 不同路径

题目描述:

一个机器人位于一个 m x n 网格的左上角 ,机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。问总共有多少条不同的路径?

思路:

其实就是问(0,0)->(m-1,n-1)一共有几条路。

第一个方法:数学上排列组合

第二个方法:

动态规划。抓住语句:机器人每次只能向下或者向右移动一步,所以动态规划转移方程为dp[i][j]=dp[i-1][j]+dp[i][j-1];考虑边界情况,dp[0][j],从(0,0)->(0,j)一共只有1条路(横着走)dp[i][0]同理只能竖着走。

所以代码如下:

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> dp(m, vector<int>(n, 1)); // 初始化二维数组并将所有值初始化为1
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
};

本题over


152. 乘积最大子数组

题目描述:

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

思路:

哲哲这道题典型动态规划的背包问题。用dp[i][j]表示从i到j的最大结果,要求连续,可以重新开始,也可以是上一个的结果乘nums[j],来吧状态转移方程:dp[i][j]=max(nums[j],dp[i][j-1]*nums[j])。最后的结果就是返回dp数组里的最大值就可以。但还记得之前有一篇也是类似的做法,后来采用临时变量+max的方法,将复杂度降低么?所以这次依然尝试。

但是!!!显然我忘记了一件事负负得正这个问题。这样会存在跳过的情况。所以方案pass

 但还记得之前有一篇也是类似的做法,后来采用临时变量+max的方法,将复杂度降低么?所以这次依然尝试。(但这句话依然有效)

重新分析:

1.连续想乘,什么情况下会变小?1.*0 直接=0;2.*负数;但负数,会有一个负负得正的情况。所以我们不妨将负数的结果也存下来。

2.转移方程dp[i][j]=max(nums[j],dp[i][j-1]*nums[j])。设置为临时变量+max

于是有了方法:

在计算最大乘积时,我们同时考虑当前位置的值当前位置乘上前一个位置的最大乘积、当前位置乘上前一个位置的最小乘积这三种情况。

我们可以使用两个变量 max_prodmin_prod 来分别记录当前位置之前的最大乘积和最小乘积。然后我们遍历数组,对于每个位置的元素,更新 max_prodmin_prod,并根据当前位置的值、当前位置乘上前一个位置的最大乘积、当前位置乘上前一个位置的最小乘积这三者之间的关系来更新这两个变量。

具体的代码逻辑如下:
  • 用 max_prod 和 min_prod 分别记录当前位置之前的最大乘积和最小乘积,初始化为第一个元素 nums[0]
  • 从第二个元素开始遍历数组,对于每个位置的元素,如果该元素是负数,则交换 max_prod 和 min_prod,因为乘以负数会导致最大值变成最小值,最小值变成最大值。
  • 更新 max_prod 和 min_prod,分别取当前位置的值、当前位置乘上前一个位置的最大乘积、当前位置乘上前一个位置的最小乘积中的最大值和最小值。
  • 在更新 max_prod 的过程中,不断维护全局的最大乘积 result

通过这种方法,我们在遍历数组的过程中不断更新 max_prodmin_prodresult,最终得到的 result 就是乘积最大的子数组的乘积。

顺便举个例子:

假设给定数组 nums = [2, 3, -2, 4],我们来计算乘积最大的连续子数组。

初始时,我们有:
max_prod = 2 (以第一个元素结尾的最大乘积)
min_prod = 2 (以第一个元素结尾的最小乘积)
result = 2 (全局最大乘积)

接下来,我们依次遍历数组中的元素:

对于第二个元素 3:
更新 max_prod = max(3, 2 * 3) = 6,min_prod = min(3, 2 * 3) = 3
更新 result = max(result, 6) = 6

对于第三个元素 -2:
因为是负数,交换 max_prod 和 min_prod
更新 max_prod = max(-2, 6 * -2) = -2,min_prod = min(-2, 6* -2) = -12
更新 result = max(result, -2) = 6

对于第四个元素 4:
更新 max_prod = max(4, -2 * 4) = 4,min_prod = min(4, -12 * 4) = -48
更新 result = max(result, 4) = 6
最终得到的结果是 6,即数组中乘积最大的连续子数组的乘积为 6。

代码如下:

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) return 0;

        int max_prod = nums[0];
        int min_prod = nums[0];
        int result = nums[0];

        for (int i = 1; i < n; i++) {
            if (nums[i] < 0) {
                swap(max_prod, min_prod);
            }

            max_prod = max(nums[i], max_prod * nums[i]);
            min_prod = min(nums[i], min_prod * nums[i]);

            result = max(result, max_prod);
        }

        return result;
    }
};

198. 打家劫舍

题目:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

思路:

动态规划,当前一个偷完之后,下一个一定不能偷,但下下一个不一定。………………这样思考比较麻烦,不妨倒过来思考。

假设,我第k个房间,当前的值记为dp[k];则有两种情况:1,上一个房间我投过了,这个房间我不能投;2,上一个房间我没投,我投这个房间。所以dp就有以下表达式

dp[k]=max(dp[k-1],dp[k-2]+nums[k-1])

边界情况:

dp[0]=0; 
dp[1]=nums[0];dp[2]=max(nums[0],nums[1]);
//dp[2]=max(nums[0],dp[2-2]+nums[1]);

 推荐题解:. - 力扣(LeetCode) 

好,于是代码如下:(这个用常量优化有点难,所以先写不优化的)

class Solution {
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
        if(n==0) return 0;
        if(n==1) return nums[0];
        vector<int>dp(n+1);
        dp[0]=0;//dp.push_back(0);//
        dp[1]=nums[0];
        dp[2]=max(nums[0],dp[0]+nums[1]);
        for(int i=3;i<=n;i++){
            dp[i]=max(dp[i-1],dp[i-2]+nums[i-1]);
        }
        return dp[n];
    }
};

性能太差,优化一下:

优化方法:两个常量+max;(前面两道题也是这样做的,要学会)

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if (n == 0)
            return 0;
        if (n == 1)
            return nums[0];
        int prev1 = 0; // 用于存储偷窃到当前房屋的最大价值
        int prev2 = 0; // 用于存储偷窃到前一间房屋的最大价值

        for (int i = 0; i < n; ++i) {
            int temp = prev1; // 临时变量存储偷窃到当前房屋的最大价值
            prev1 =max(prev2 + nums[i], prev1); // 更新当前房屋的最大偷窃价值
            prev2 = temp; // 更新前一间房屋的最大偷窃价值
        }

        return prev1; // 返回最后一间房屋的偷窃价值即为最终答案
    }

};

今日结束ocver


总结一下动态规划的模板吧

动态规划问题的一般解题思路可以总结为以下几个步骤:

  1. 定义状态:明确定义dp数组的含义,即每个元素dp[i]代表的是什么状态,可以是最大值、最小值等。

  2. 初始化:根据问题的要求对dp数组进行初始化,将初始条件赋给dp数组中相应的元素。

  3. 状态转移方程:找出状态之间的转移关系,即如何通过已知的状态推导出未知的状态。这是动态规划问题的核心,也是最难的部分。

  4. 递推计算:通过循环遍历或者递归的方式填充dp数组,根据状态转移方程更新每个位置的值。

  5. 返回结果:根据问题的要求从dp数组中得到最终的结果,可能是dp数组的最后一个元素,也可能是整个dp数组中的最大/最小值等。

代码:

// 初始化dp数组
vector<int> dp(n, initial_value);

// 处理边界条件
dp[0] = initial_condition;

// 状态转移方程计算dp数组的值
for (int i = 1; i < n; ++i) {
    // 根据状态转移方程更新dp[i]
    dp[i] = update_function(dp, i, other_parameters);
}

// 返回最终结果
return final_result;

说在最后,

其实动态规划最核心的就是找出地推关系式。可以抽象的想第k个状态,往前倒退,找出关系式,用1,2,临街情况测试状态方程是否正确。最后再讲dp数组改进为常量,节省空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

30岁失业的我,选择职场转型,进入AIGC工程师领域,重新开始

去年&#xff0c;刚满30岁的我又一次被公司辞退了&#xff0c;由于学历不高&#xff0c;简历也不出彩&#xff0c;尽管半个月来投了一份又一份的简历&#xff0c;但仍然是石沉大海&#xff0c;我终于不得不开始思考一个以前被我一直刻意压制的想法——职场转型。 尽管知道这条…

docker (一)

1&#xff0c;什么是docker 首先我们可以好好的看看docker的那个可能的图标&#xff0c;你想象到了什么&#xff1f; ... docker是一个开源的应用容器引擎&#xff0c;有Docker公司&#xff08;前dotCloud公司&#xff09;开发&#xff0c;基于Apache2.0开源授权协议发行。该…

碳实践|企业组织碳排放源识别方法、案例分析,及注意事项

在上一章中讲到“界、源、算、质、查”五步法实现企业组织碳的完整核算流程&#xff0c;本章将针对其中的“源”- “识别排放源”这一步骤来展开,主要分析其识别方法、实操案例&#xff0c;并列举注意事项。 企业识别碳排放源是指在组织边界内找到产生碳排放的设施&#xff0c;…

算法沉淀 —— 动态规划篇(路径问题)

算法沉淀 —— 动态规划篇&#xff08;路径问题&#xff09; 前言一、不同路径1二、珠宝的最高价值三、下降路径最小和四、地下城游戏 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都将基于此 1.、状态表示&#xff1a;通常状态表示分为以下…

登录校验解决方案JWT

目录 &#x1f397;️1.JWT介绍 &#x1f39e;️2.应用场景 &#x1f39f;️3.结构组成 &#x1f3ab;4.JWT优点 &#x1f3a0;5.封装成通用方法 &#x1f6dd;6.JWT自动刷新 1.JWT介绍 官网&#xff1a;JWT官网 JSON Web Token (JWT) 是一个开放标准&#xff0c;它…

C语言:编译与链接

目录 前言1. 翻译环境与运行环境2.翻译环境&#xff1a;预编译编译汇编链接3. 运行环境 前言 我们写一个程序&#xff0c;例如test.c或是test.h这些源文件&#xff0c;头文件&#xff0c;事实上这些代码都是文本文件&#xff0c;但是计算机能够看得懂&#xff0c;并且直接执行…

C#代码混淆器 ipaguard 的优势与使用

摘要 本文探讨了iOS开发的优势、费用以及软件开发方面的相关内容。通过分析iOS开发所采用的编程语言、开发环境、用户界面设计、应用审核流程以及应用领域等方面&#xff0c;展示了iOS开发的诸多优势和特点。虽然iOS开发具有高用户体验、统一的硬件和软件环境、良好的市场份额等…

uni-app中web-view的使用

1. uni-app中web-view的使用 uni-app中的web-view是一个 web 浏览器组件&#xff0c;可以用来承载网页的容器&#xff0c;uni-app开发的app与web-view实现交互的方式相关简单&#xff0c;应用通过属性message绑定触发事件&#xff0c;然后在web-view的网页向应用 postMessage 触…

博途PLC 系统时间读取写入功能块

系统时间数据类型属于DTL数据类型,DTL本身是结构变量,有时、分、秒、纳秒。利用纳秒寄存器可以实现伪随机数发生器,伪随机数发生器详细代码介绍请参考下面文章链接: 1、伪随机数 https://rxxw-control.blog.csdn.net/article/details/122157365https://rxxw-control.blog…

电脑桌面记事本便签软件,记事本软件哪个好

在这个快节奏的生活中&#xff0c;我们每个人都需要一个得力的助手来帮助我们管理琐碎的事务。作为一名忙碌的职场人士&#xff0c;你是否经常因为忘记重要事项而感到焦虑&#xff1f;是否因为繁杂的待办事项而感到无从下手&#xff1f;今天&#xff0c;我要向你推荐的这款电脑…

Git相关命令(一)

一、简介 Git 是一个开源的分布式版本控制系统。 当然&#xff0c; git 不会傻傻的把你的每一个版本完整的存储下来&#xff0c;他仅仅会存储每次修改的位置和内容&#xff08;可持久化&#xff09;&#xff0c;每一次 commit 可以理解为产生一个版本&#xff0c;接下来的版本…

第二十章 javascript使用

文章目录 1. JS基中基1. 注释2. 弹窗3. 引入JS代码4. JS的基本数据类型5. 变量6. 字符串的操作 2. 条件分支3. 循环4. JS中的函数1. 闭包函数(自运行函数) 5. 定时器 1. JS基中基 1. 注释 HTML的注释 <!– –>JS的注释 // 单行注释 /* */多行注释 2. 弹窗 alert(“我…

C语言例4-18:从键盘输入平面上一个点的坐标值,判断其所在的象限。

代码如下&#xff1a; //从键盘输入平面上一个点的坐标值&#xff0c;判断其所在的象限。 #include<stdio.h> int main(void) {float x,y;printf("输入平面上一个点的坐标值\n");printf("x");scanf("%f",&x); //从键盘输入平面上一个…

使用npm i进行admin依赖安装的时候出现问题

提示&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/string-width failed, reason: certificate has expired 切换淘宝源到http或者更换其他国内镜像 npm config set registry http:/…

第十三届蓝桥杯省赛真题 Java 研究生 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 排列字母试题 B: 灭鼠先锋试题 C: 质因数个数试题 D: 数位排序试题 E: 蜂巢试题 F : \mathrm{F}: F: 爬树的甲壳虫试题 G: 重新排序试题 H \mathrm{H} H : 技能升级试题 I: 最优清零方案试题 J : \mathrm{J}: J: 推导部分和 发现宝藏 …

赵本山:这眼睛不好他也嫉妒,潘长江:上看台是好事不过我这腿上不去!

赵本山&#xff1a;这眼睛不好他也嫉妒&#xff0c;潘长江&#xff1a;上看台是好事不过我这腿上不去&#xff01; ——小品《大观灯》&#xff08;中4&#xff09;的台词 &#xff08;接上&#xff09; 赵本山&#xff08;瞎子&#xff09;&#xff1a;你说这咋又挪这来了你说…

Linux课程____shell脚本应用

一、认识shell 常用解释器 Bash , ksh , csh 登陆后默认使用shell&#xff0c;一般为/bin/bash&#xff0c;不同的指令&#xff0c;运行的环境也不同 二、 编写简单脚本并使用 # vim /frist.sh //编写脚本文件&#xff0c;简单内容 #&#xff01;/bin/bash …

日常刷题之77-组合

题目 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示&#xff1a;假设 n5,k3 就是需要组合出来&#xff0c;长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次&#…

买卖股票的最佳时机1,2,3

买卖股票的最佳时机 力扣题目链接 dp[i][0] 表示第i天持有股票所得最多现金 定义二维数组 两列 &#xff1a;0代表持有股票 1代表不持有股票 行代表第几天 dp[i][0] max(dp[i - 1][0], -prices[i]); 第i天持有股票&#xff1a;两种情况 第一种是昨天就已经持有股票了 所…

电脑桌面记事本便签软件,好用的桌面记事本

在快节奏的生活中&#xff0c;我们常常需要记录一些重要事项&#xff0c;以便随时查看和提醒自己。然而&#xff0c;传统的便签容易丢失、难以管理&#xff0c;让我们感到困扰。在这种情况下&#xff0c;一款好用的电脑桌面便签软件就显得尤为重要。今天&#xff0c;小编为大家…