【力扣刷题 | 第十五天】

news2024/11/24 16:18:12

目录

前言:

 ​​​​​​​63. 不同路径 II - 力扣(LeetCode)

343. 整数拆分 - 力扣(LeetCode)

总结:


前言:

        本篇我们主要刷动态规划的题,解题还是严格按照我们在【夜深人静写算法】栏目下的解题步骤,大家如果没学过动态规划的可以先看看我写的动态规划文章介绍。

【夜深人静学数据结构与算法 | 第十篇】动态规划_我是一盘牛肉的博客-CSDN博客

 

 ​​​​​​​63. 不同路径 II - 力扣(LeetCode)

一个机器人位于一个 m * n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

其实这题跟我们在动态规划中讲解的例题答题思路基本一致,就是需要再加一个判断条件:
如果这块是障碍点,那么我们就将这个点的路径数设置为0,并且放弃这条路。

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
	if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) //如果在起点或终点出现了障碍,直接返回0
       { 
            return 0;
       }    
        vector<vector<int>> dp(m, vector<int>(n, 0));
        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++)//obstacleGrid[i][0] == 0也就是没有障碍物
        {
            dp[i][0] = 1;
        } 
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++)// obstacleGrid[0][j] == 0也就是没有障碍物
        {
             dp[0][j] = 1;
        };

        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1)
                {
                    continue;
                } 
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];

    }
};

343. 整数拆分 - 力扣(LeetCode)

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

 其实这道题我们要明白:要想使得拆出来的整数乘积大,我们就要尽量的保证拆出来的整数接近。也就是尽可能拆出来相同的数。

关于为什么是这样的,我们需要用数学公式解决:

这个问题可以通过数学方法进行解释,思路如下:

假设将整数 n 拆分成 k 个正整数相加,这 k 个正整数分别为 a1, a2, ..., ak,则它们的乘积为:

P = a1 * a2 * ... * ak

我们可以对这个乘积进行求导,得到:

dP/da1 = a2 * a3 * ... * ak
dP/da2 = a1 * a3 * ... * ak
...
dP/da(k-1) = a1 * a2 * ... * a(k-1)
dP/da(k) = a1 * a2 * ... * a(k-1)

由于这k个正整数相加得到的和为n,因此有:

a1 + a2 + ... + ak = n

可以使用拉格朗日乘数法求解上面的一组方程,得到:

a1 = n / k
a2 = n / k
...
ak-1 = n / k
ak = n - (k-1) * n / k

可以看到,当 k 越大时,每个数都越趋近于相等,因此其乘积也会越来越大,直到取到最大值。

因此,我们可以通过枚举每个 k,来找到乘积最大的 k 和对应的乘积。

看不懂也没有关系,知道这个结论就可以了,但是如果更好的理解这个数学验证的话,我们就可以在验证的时候做更好的优化。

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n + 1);
        dp[2] = 1;
        for (int i = 3; i <= n ; i++) {
            for (int j = 1; j <= i / 2; j++) {
                dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
            }
        }
        return dp[n];
    }
};

但其实本道题还可以用贪心算法的思路来做,但是贪心算法的代码虽然简洁,但是数学公式证明起来比较麻烦。

本题是可以用贪心算法进行求解的。

1. 当n>=5时,将n拆分成3和n-3的和,比将其拆分成2和n-2的和要优秀,即:

            n-3 > n-2 && 3*(n-3) > 2*(n-2)
   
   这个性质可以通过一系列代数计算证明。

2. 当n>=5时,将n拆分成3的个数不会小于将其拆分成2的个数,即:

            n mod 3 <= 1
   
   这个性质也可以通过一系列代数计算证明。

基于以上结论,可以采用贪心算法,将整数n尽可能地拆分成3的和,直到最后得到的整数小于5。如果最后得到的整数等于1,则将其与最后一个3合并为4。

这种贪心策略的正确性可以通过数学归纳法证明。这里只给出其中一个例子:

        当n=6时,根据以上贪心策略,将其拆分成3和3的和,乘积为9。然而,将其拆分成2和2和2的和,乘积为8,不是最优解。但是,当n=5时,按照贪心策略,将其拆分成3和2的和,乘积为6;而将其拆分成2和3的和,乘积为5,不是最优解。又因为任何大于5的整数都可以通过一系列的拆分得到6和2或3的和,因此对于所有大于5的整数,采用贪心策略是最优的。

因此,可以使用贪心算法来解决这个问题。

class Solution {
public:
    int integerBreak(int n) {
        if (n == 2) return 1;
        if (n == 3) return 2;
        if (n == 4) return 4;
        int result = 1;
        while (n > 4) {
            result *= 3;
            n -= 3;
        }
        result *= n;
        return result;
    }
};

总结:

        在做动态规划的时候,我们如果是初学的话,要牢牢按照动态规划五步走,这样才可以完整的解题,而不是稀里糊涂的看题解。

如果我的内容对你有帮助,请点赞,评论,收藏创作不易,大家的支持就是我坚持下去的动力!

 

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

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

相关文章

Linux查看文件大小

1、Linux下查看文件和文件夹大小 当磁盘大小超过标准时会有报警提示&#xff0c;这时如果掌握df和du命令是非常明智的选择。 df可以查看一级文件夹大小、使用比例、档案系统及其挂入点&#xff0c;但对文件却无能为力。 du可以查看文件及文件夹大小。 两者配合使用&#xf…

UE中创建可脚本化编辑器工具(Scriptable Tools)

UE5.2中提供了可脚本化工具编辑模式&#xff0c;该模式下用户可以编写蓝图节点自定义界面操作模式下的逻辑&#xff0c;例如重写鼠标点击事件&#xff0c;制作自定义画刷等。 如果你不太了解UE编辑器工具&#xff0c;可以参考这篇文章&#xff1a; https://blog.csdn.net/gray…

chatgpt赋能python:Python编程计算一元二次方程——最简单的方法实现

Python编程计算一元二次方程——最简单的方法实现 前言 Python编程语言是一种优秀的开源编程语言&#xff0c;具有易于学习、代码简洁明了、易于维护等优点&#xff0c;因此在近年来得到了广泛的应用。 本文将介绍如何使用Python编写一个简单而又实用的计算一元二次方程的程…

华为认证哪个方向考的人多?考试费用是多少?

从学校毕业后&#xff0c;就要走上社会了&#xff0c;很多人就要面临就业困难&#xff0c;对于信息通信行业的人来说&#xff0c;考一份技术证书&#xff0c;是可以帮助自己提高职业竞争力、获得好工作的方法。华为云认证是华为云旗下的认证&#xff0c;其设立时间长&#xff0…

多线程爬虫实战-思路

前言 最近有很多小伙伴找到我&#xff0c;说想要王者荣耀所有英雄皮肤的照片&#xff0c;但是又不想自己去下载&#xff0c;正好借这个机会给大家讲解一下多线程的爬虫实战 由于线程爬虫会对任何服务器都有一定的影响&#xff0c;本文仅供学习交流使用&#xff0c;切勿拿去做什…

PID原理及仿真程序套用(matlab仿真与图像处理系列第3期)

PID控制器模拟器 概述: PID控制器是一种常用的反馈控制算法,用于实现系统输出与期望值之间的精确调节。PID控制器模拟器是一个工具,可以模拟和测试PID控制器的性能,并对系统进行调整和优化。 输入参数: setpoint:期望值或目标值process_variable:过程变量或实际测量…

go中map哈希表使用总结

作者&#xff1a;程序员CKeen 博客&#xff1a;http://ckeen.cn​​​​​​​ 长期坚持做有价值的事&#xff01;积累沉淀&#xff0c;持续成长&#xff0c;升维思考&#xff01;希望把编码做为长期爱好&#x1f604; 在 Go 语言中&#xff0c;map是一种基于哈希表实现的数据结…

设计模式之解释器模式笔记

设计模式之解释器模式笔记 说明Interpreter(解释器)目录解释器模式示例类图抽象表达式类环境角色类封装变量的类加法表达式类减法表达式类测试类 说明 记录下学习设计模式-解释器模式的写法。JDK使用版本为1.8版本。 Interpreter(解释器) 意图:定义一个语言&#xff0c;定义…

chatgpt赋能python:Python编程:如何将程序变成软件

Python编程&#xff1a;如何将程序变成软件 Python是一种非常流行的编程语言&#xff0c;因为它具有简单易学、高效和灵活等优点。许多人使用Python编写程序&#xff0c;但他们可能不知道如何将这些程序变成可执行的软件。在本文中&#xff0c;我们将介绍Python程序如何成为软…

【C/C++数据结构】链表与快慢指针

目录 一、单链表 二、双向循环链表 三、判断链表是否带环 四、链表的回文结构判断 五、复制带随机指针的链表 一、单链表 优点&#xff1a;头部增删效率高&#xff0c;动态存储无空间浪费 缺点&#xff1a;尾部增删、遍历效率低&#xff0c;不支持随机访问节点 头结点&…

【Linux | Shell】bash shell 基础命令

目录 一、概述二、启动shell2.1 用户的默认 Shell 程序2.2 Shell 提示符 三、 基础命令3.1、man 命令3.2、cd 命令3.3、ls命令 一、概述 很多 Linux 发行版的默认 shell 是 GNU bash shell。本文将介绍 bash shell 的基本特性&#xff0c;比如 bash 手册、命令行补全以及如何显…

JavaWeb 第一个Servlet程序

1.Servlet Servlet是Java编写的用于Web应用程序的服务器端程序。 它可以接收来自Web浏览器的HTTP请求并生成响应。 Servlet通常用于创建动态Web内容&#xff0c;例如网页、表单处理、登录和数据库访问等。 Servlet是Java EE&#xff08;Enterprise Edition&#xff09;规范…

[补充]托福口语21天——day2 课堂内容

day1 课堂&#xff1a;http://t.csdn.cn/cyvZm day1 语料&#xff1a;http://t.csdn.cn/syTBy 目录 1 时间准备 2 例题 3 答题步骤 3.1 范例 3.2 范例 4 连接词 5 完整回答 5.1 范例 5.2 范例 6 总结 背背背&#xff01; 1. 如今的生活成本非常高。人们要付…

学习系统编程No.25【核心转储实战】

引言&#xff1a; 北京时间&#xff1a;2023/6/16/8:39&#xff0c;实训课中&#xff0c;大一下学期最后有课的一天&#xff0c;还有两天就要期末考啦&#xff01;目前什么都还没有复习&#xff0c;不到星期天晚上&#xff0c;咱不慌&#xff0c;小小挂科&#xff0c;岂能拦得…

postgresql_internals-14 学习笔记(六)—— 统计信息

不完全来自这本书&#xff0c;把查到的和之前的文章重新汇总整理了一把。 一、 统计信息的收集 1. 主要参数 其中最主要的是track_counts&#xff0c;开启才会收集统计信息。 postgres# select name,setting,short_desc,context from pg_settings where name like track%; na…

LeetCode 周赛 351(2023/06/25)T2 有点意思

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问。 往期回顾&#xff1a;LeetCode 单周赛第 348 场 数位 DP 模版学会了吗&#xff1f; T1. 美丽下标对的数目&#xff08;Easy&#xff09; 标签&am…

python爬虫并做可视化分析--前程无忧

一.数据采集 1.采集逻辑 2.数据schema 招聘信息Schema { "岗位名称": "财务会计主管", "薪资":"1.3-2万", "地址": "*******", "经验要求": "5-7年", "公司名": "***…

JDK8新特性-上部

文章目录 一、Java发展史1.1 发展史1.2 OpenJDK和OracleJDK1.3 Open JDK 官网介绍 二、Lambda表达式2.1 需求分析2.2 Lamada表达式的体验2.3 Lambda表达式的语法规则2.3.1 Lambda表达式练习2.3.2 Lambda表达式练习 2.4 Lambda表达式的使用前提2.5 FunctionalInterface注解2.6 L…

MATLAB | 如何使用MATLAB获取顶刊《PNAS》绘图(附带近3年图像)

千呼万唤始出来&#xff0c;《PNAS》绘图获取的代码来啦&#xff0c;不过这次研究了半天也没想到如何获取付费文章的绘图&#xff0c;就只下载了免费文章(主要也怕侵权)&#xff0c;不过光免费文章的图片三年了也有接近1.7w张了&#xff0c;同时使用代码下载时依旧需要科学上网…

【Redis】Redis的数据结构

【Redis】Redis的数据结构 文章目录 【Redis】Redis的数据结构1. 动态字符串SDS2. IntSet2.1 IntSet升级 3. Dict3.1 Dict的扩容3.2 Dict的收缩3.3 Dict的rehash 4. ZipList4.1 ZipList中的Entry4.1.1 Encoding编码 4.2 ZipList的连锁更新问题4.3 特性 5. QuickList 1. 动态字符…