DP刷题(一)

news2024/9/28 5:24:55

目录

拆分单词 牛客题霸_牛客网

 【思路梳理】​

剑指 Offer II 100. 三角形中最小路径之和

【解法一】自顶向下

【解法二】自底向上

路径的数目 剑指 Offer II 098. 路径的数目

 【解法一】

 【解法二】

路径的数目(加入障碍物)63. 不同路径 II

 【解法一】原数组上进行操作(空间换时间……)

【解法二】优化版


拆分单词

 【思路梳理】

 

 

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        vector<bool> res(s.size()+1, false);
        res[0] = true;
        for(int i = 1; i <= s.size(); i++)
        {
            for(int j = i-1; j >=0; --j)
            {
                if(res[j] && dict.find(s.substr(j,i-j))!=dict.end())
                {
                    res[i] = true;
                    break;
                }
            }
        }
        return res[s.size()];
    }
};


【解法一】自顶向下

状态:F[i,j] 表示从【0,0】到【i,j】的最小路径和

状态转移方程为:

 初始条件:F[0,0] = array[0][0]

返回结果min(F[row-1,j);

思想划分:

① 更新三角形的俩条边,对于斜边来说只能是从前一个到后一个,所以数值更新为前一个加上自身元素值。

 

② 更新三角形内部元素,从第三行第二列开始,将值更新为前一行本列与前一行前一列的最小值加上当前值

③ 找到最后一行中最小的元素值(11即为所求)

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        int row = triangle.size();
        int col = triangle[row-1].size();
        // 1、初始化三角形的俩个斜边
        for(int i = 1; i < row; ++i)
        {
            for(int j = 0; j < triangle[i].size(); j++)
            {
                if(j==0)
                {
                    triangle[i][j] = triangle[i-1][j] + triangle[i][j];
                }
                else if(i==j)
                {
                    triangle[i][j] = triangle[i-1][j-1] + triangle[i][j];
                }
            }
        }
        // 2、初始化三角形内部元素
        for(int i = 2; i < row; ++i)
        {
            for(int j = 1; j < triangle[i].size()-1; j++)
            {
                triangle[i][j] = min(triangle[i-1][j], triangle[i-1][j-1])+triangle[i][j];
            }
        }
        // 3、找到初始化之后三角形最后一行中最小的元素
        int min = triangle[row-1][0];
        for(int j = 1; j < triangle[row-1].size(); ++j)
        {
            if(triangle[row-1][j]<min)
            min = triangle[row-1][j];
        }
        return min;
    }
};

【解法二】自底向上

状态F[i,j] 从【i,j】到 最底行的最小路径和

状态转移方程F[i,j] = min(F[i+1,j], F[i+1, j+1]) + array[i][j]

初始状态 F[row-1, j] = array[row-1][j]

返回结果 F[0, 0]

 

 

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        // F[i,j] = triangle[row-1][j]
        int row = triangle.size();
        for(int i = row-2; i >= 0; --i)
        {
            for(int j = 0; j < triangle[i].size(); ++j)
            {
                triangle[i][j] = min(triangle[i+1][j],triangle[i+1][j+1])+
                                 triangle[i][j];
            }
        }
        return triangle[0][0];
    }
};


路径的数目

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

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

问总共有多少条不同的路径?

 

 【思路梳理】

 【解法一】

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> res(m, vector<int> (n, 1));
        for(int i = 1; i < m; i++)
            for(int j = 1; j < n; j++)
                res[i][j] = res[i-1][j] + res[i][j-1];
        return res[m-1][n-1];
    }
};

 【解法二】

        vector<vector<int>> res(m, vector<int> (n,0));
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(i==0&&j==0)
                    res[i][j]=1;
                else
                {
                    if(i)res[i][j] += res[i-1][j];
                    if(j)res[i][j] += res[i][j-1];
                }
            }
        }
        return res[m-1][n-1];

路径的数目(加入障碍物)

 

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

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

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

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

 【解法一】原数组上进行操作(空间换时间……)

1、对终点和起点有无障碍物的判断

2、在原数组上将障碍物置为-1
      将第一行和第一列不为障碍物的元素置为1
      如果第一行或第一列有障碍物,就将其后续元素全部置为-1

3、对数组其余元素进行访问
      注意对出口的俩个方向都为障碍物的判断

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& res) {
        int row = res.size();
        int col = res[0].size();
        // 1、对终点和起点有无障碍物的判断
        if(res[row-1][col-1]==1||res[0][0]==1)
        return 0;
        res[row-1][col-1] = 0;
        // 2、在原数组上将障碍物置为-1
        //    将第一行和第一列不为障碍物的元素置为1
        //    如果第一行或第一列有障碍物,就将其后续元素全部置为-1
        for(int i = 0; i < row; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(res[i][j]==0)
                {
                    if(i==0 || j==0)
                        res[i][j] = 1;
                }
                else
                    res[i][j] = -1;
            }
        }
        for(int i = 1; i < row; i++)
        {
            if(res[i][0]==-1)
            {
                i++;
                while(i<row)
                {
                    res[i++][0]=-1;
                }
                break;
            }
        }
        for(int j = 1; j < col; j++)
        {
            if(res[0][j]==-1)
            {
                j++;
                while(j<col)
                {
                    res[0][j++]=-1;
                }
                break;
            }
        } 
        // 3、对数组其余元素进行访问
        //    注意对出口的俩个方向都为障碍物的判断
        for (int i = 1; i < row; i++)
		{
			for (int j = 1; j < col; j++)
			{
				if (res[i][j] == -1)
				{
					continue;
				}
				else
				{
                    if(i==row-1&&j==col-1&&res[i - 1][j] == -1 && res[i][j - 1] == -1)
                    {
                        return 0;
                    }
					else if (res[i - 1][j] == -1 && res[i][j - 1] == -1)
						res[i][j] = -1;
					else if (res[i - 1][j] == -1)
						res[i][j] = res[i][j - 1];
					else if (res[i][j - 1] == -1)
						res[i][j] = res[i - 1][j];
					else
						res[i][j] = res[i - 1][j] + res[i][j - 1];
				}
			}
		}
        return res[row-1][col-1];
    }
};

【解法二】优化版

 用0填充新开辟一个数组,省去了上述第二步诸多操作

1、首先进行正常的出入口都是障碍物的判断

2、新建数组并且全部赋值为0的好处就是不用对第一行第一列进行遇到障碍物就要清除后续路径的操作

3、直接用下标访问路径上没有障碍物的路径,从0,0下标一路出发,对每个不是障碍物的结点进行赋值,利用俩个if判断i j是否为零,如果不是第一行,那么就可以从上方来,如果不是第一列就可以从左边来。

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& o) {
        int m = o.size();
        int n = o[0].size();
        if(o[m-1][n-1]==1 || o[0][0]==1)
        return 0;
        vector<vector<int>> res(m, vector<int> (n, 0));
        res[0][0] = 1;
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(o[i][j]==0)
                {
                    if(i)res[i][j] += res[i-1][j];
                    if(j)res[i][j] += res[i][j-1];
                }
            }
        }
        return res[m-1][n-1];
    }
};

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

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

相关文章

unity 简单实现三阶魔方游戏

unity 简单实现三阶魔方游戏 魔方体验地址 工程文件免费下载 实现思路 一、魔方的旋转 三阶魔方由26个方块与 9个旋转轴组成。旋转轴旋转时带动在其控制范围的方块旋转。 旋转轴如何带动方块旋转&#xff1f; 把旋转轴控制范围内的方块设置成旋转轴的子物体&#xff0c;…

必背经典!这些软件测试面试题及答案别放过!

对于很多软件测试新手来说&#xff0c;技术面试往往是整个面试体系里最让人头疼的部分&#xff0c;今天我为选取了软件测试面试中&#xff0c;一些经典的问题和答案&#xff0c;供大家参考使用。并且&#xff0c;还给你们奉上了一个免费的面试刷题小程序哟&#xff01;拿走不谢…

调试前端代码二三事--(一)-调试基础

一&#xff0c;在网页上调试代码 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…

房产管理系统中CAD图形管理分析

随着技术的不断进步和升级&#xff0c;以及高校房屋建筑物数量的不断扩充&#xff0c;建立房屋资产管理信息系统进行信息化、数字化、图形化房屋资产管理已经是势在必行。学校有庞大的房屋数据、大量的CAD图纸、复杂的房屋分类&#xff0c;建设房屋管理系统&#xff0c;能够加强…

JavaSE高级篇:运行时数据区

文章整理自深入理解Java虚拟机第一章概述第二章&#xff1a;运行时数据区域一&#xff1a;程序计数器二&#xff1a;Java虚拟机栈三&#xff1a;Java堆四&#xff1a;方法区五&#xff1a;运行时常量池六&#xff1a;直接内存第一章概述 Java程序员把内存控制的权利交给了JVM …

Spring MVC 获取参数

1..获取参数 得到单个参数&#xff1a; 运行结果&#xff1a; 得到俩个参数&#xff1a; 运行结果&#xff1a; 得到多个参数&#xff08;对象&#xff09; 运行结果&#xff1a; 通过表单传递参数&#xff1a; 但是&#xff0c;如果我用json传递就不行了&#xff0c;namenul…

【回答问题】ChatGPT上线了!给我推荐20个比较流行的3D点云分割模型

给我推荐20个比较流行的点云 3D 分割模型 这里是 20 个比较流行的点云 3D 分割模型: PointNet PointNet PointCNN Kd-Net SpiderCNN PointSIFT PointASNL PointGroup PointConv PointWeb PointGNN PointPillars PointSESA PointSNE DensePoint PointSAP PointSGN PointGCN Po…

Java 应用与数据库的关系

1.什么是数据库• 数据库就是用来存储和管理数据的仓库• 数据库存储数据的优先。2.数据库的优点• 可存储大量数据;方便检索;• 保持数据的一致性、完整性﹔安全&#xff0c;可共享;• 通过组合分析,可产生新数据。3.数据库的发展历程• 没有数据库,使用磁盘文件存储数据,层次…

2022年度AI亮点项目大起底,ChatGPT是你心目中的第一吗?

回顾2022年&#xff0c;人工智能取得了巨大进步&#xff0c;我有一种感觉&#xff0c;人工智能正在扭曲我的时间感官。谁能相信Stable Diffusion只有4个月大&#xff0c;而ChatGPT的出现才一个多月&#xff1f;感觉只是眨了眨眼&#xff0c;我们差点错过了一个全新的行业。 在过…

Effective_Objective-C_4协议与分类】

文章目录前言23.通过委托与数据源协议进行对象间的通信协议委托模式数据源模式要点总结24.将类的实现代码分散到便于管理的数个分类之中分类Xcode创建一个分类分类需要注意什么要点25.总是为第三方的分类名称加前缀要点26.切勿在分类里面声明属性关联对象扩展可以添加属性要点2…

用javascript分类刷leetcode20.字符串(图文视频讲解)

1143. 最长公共子序列 (medium) 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删…

系分 - UML【概念】

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录UML - Unified Modeling LanguageUML中有4种事物结构事物行为事物分组事物注释事物UML图的分类结构型图&#xff08;静态图&#xff09;行为型图&#xff08;动态图&#xff09;UML图 - 静态图[结构型]类图…

C#枚举器和迭代器

C#枚举器和迭代器 使用foreach语句时&#xff0c;可以依次取出数组里面的元素&#xff0c;原因就是数组提供了“枚举器&#xff08;Enumerator&#xff09;”&#xff0c;枚举器知道元素的位置并返回请求项。 枚举器IEnumerator 枚举器实现了IEnumerator接口&#xff0c;该接…

Angular页面使用指令和路由守卫进行权限控制

在各种业务系统中&#xff0c;为了保证业务及数据安全&#xff0c;除了要求用户必须登录后才能操作外&#xff0c;还针对不同的角色对不同用户设置了各自的访问权限&#xff0c;包括确定的某个页面的权限和页面中特定元素的权限。本文记录了一种Angular页面常用的权限管理方法。…

C++:std::function模板类

一&#xff1a;function定义 类模板 std::function是一种通用的多态函数包装器&#xff0c;它的实例可以对任何可以调用的目标实体进行存储&#xff0c;复制和调用操作。简单的来说&#xff1a;C中有几种可调用对象&#xff1a;函数&#xff0c;指针&#xff0c;lambda表达式&…

区块链之开发命令行操作模块

文章目录功能介绍go语言中flag用法简介项目命令行具体实现链接&#xff1a; 区块链项目github地址项目目前进度&#xff1a;功能介绍 利用命令行操作区块链相较于图形用户界面来说&#xff0c;编写代码简单&#xff0c;同时也可以实现复杂的功能。命令行模块的功能应该满足&am…

Java学习笔记 --- JDBC(1)

一、JDBC概述 基本介绍 1、JDBC为访问不同的数据库提供了统一的接口&#xff0c;为使用者屏蔽了细节问题 2、Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统&#xff0c;从而完成对数据库的各种操作 3、JDBC原理图 JDBC带来的好处 JDBC是Java提供一套用于数…

安卓移动端调用自然语言处理nlp模型【示例+源码】

安卓可以使用许多不同的方法来调用NLP模型。其中一种方法是使用现有的自然语言处理库,例如 Apache OpenNLP、 Stanford NLP 和 NLTK。这些库提供了许多常用的 NLP 功能,如分词、词干化、命名实体识别和词性标注。另一种方法是使用 TensorFlow Lite 或其他机器学习框架来加载并…

[ins 2022] 针对已见和未见群体的群体推荐中的贝叶斯归纳学习

Bayesian inductive learning in group recommendations for seen and unseen groupshttps://www.sciencedirect.com/science/article/pii/S0020025522008933摘要群组推荐是指向一组用户&#xff08;即成员&#xff09;推荐物品。在预测相关项目时&#xff0c;模型通常会面临未…

fs 文件系统模块

1、什么是 fs 文件系统模块 fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性&#xff0c;用来满足用户对文件的操作需求。 方法名 说明 fs.readFile() 用来读取指定文件中的内容 fs.writeFile() 用来向指定的文件中写入内容 如果要在 J…