当前位置: 首页 > news >正文

市场调研公司干什么的合肥网站seo公司

市场调研公司干什么的,合肥网站seo公司,怎么把网站生成二维码,洛阳青峰做网站目录 一、(leetcode 62)不同路径 1.动态规划 1)确定dp数组(dp table)以及下标的含义 2)确定递推公式 3)dp数组的初始化 4)确定遍历顺序 5)举例推导dp数组 2.数论方…

目录

一、(leetcode 62)不同路径

1.动态规划

1)确定dp数组(dp table)以及下标的含义

2)确定递推公式

3)dp数组的初始化

4)确定遍历顺序

5)举例推导dp数组

 2.数论方法

二、(leetcode 63)不同路径 II


一、(leetcode 62)不同路径

力扣题目链接

1.动态规划

机器人从(0 , 0) 位置出发,到(m - 1, n - 1)终点。

按照动规五部曲来分析:

1)确定dp数组(dp table)以及下标的含义

dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

2)确定递推公式

想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。

此时在回顾一下 dp[i - 1][j] 表示啥,是从(0, 0)的位置到(i - 1, j)有几条路径,dp[i][j - 1]同理。

那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。

3)dp数组的初始化

首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。

for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;

4)确定遍历顺序

这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。

这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。

5)举例推导dp数组

如图所示:

62.不同路径1

以上动规五部曲分析完毕,C++代码如下:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));for (int i = 0; i < m; i++) dp[i][0] = 1;for (int j = 0; j < n; j++) dp[0][j] = 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];}
};
  • 时间复杂度:O(m × n)
  • 空间复杂度:O(m × n)

其实用一个一维数组(也可以理解是滚动数组)就可以了,但是不利于理解,可以优化点空间,建议先理解了二维,在理解一维,C++代码如下:

class Solution {
public:int uniquePaths(int m, int n) {vector<int> dp(n);for (int i = 0; i < n; i++) dp[i] = 1;for (int j = 1; j < m; j++) {for (int i = 1; i < n; i++) {dp[i] += dp[i - 1];}}return dp[n - 1];}
};
  • 时间复杂度:O(m × n)
  • 空间复杂度:O(n)

 2.数论方法

在这个图中,可以看出一共m,n的话,无论怎么走,走到终点都需要 m + n - 2 步。

62.不同路径

在这m + n - 2 步中,一定有 m - 1 步是要向下走的,不用管什么时候向下走。

那么有几种走法呢? 可以转化为,给你m + n - 2个不同的数,随便取m - 1个数,有几种取法。

那么这就是一个组合问题了。

62.不同路径2

求组合的时候,要防止两个int相乘溢出! 所以不能把算式的分子都算出来,分母都算出来再做除法。

例如如下代码是不行的。

class Solution {
public:int uniquePaths(int m, int n) {int numerator = 1, denominator = 1;int count = m - 1;int t = m + n - 2;while (count--) numerator *= (t--); // 计算分子,此时分子就会溢出for (int i = 1; i <= m - 1; i++) denominator *= i; // 计算分母return numerator / denominator;}
};

需要在计算分子的时候,不断除以分母,代码如下:

class Solution {
public:int uniquePaths(int m, int n) {long long numerator = 1; // 分子int denominator = m - 1; // 分母int count = m - 1;int t = m + n - 2;while (count--) {numerator *= (t--);while (denominator != 0 && numerator % denominator == 0) {numerator /= denominator;denominator--;}}return numerator;}
};
  • 时间复杂度:O(m)
  • 空间复杂度:O(1)

二、(leetcode 63)不同路径 II

力扣题目链接

有障碍的话,其实就是标记对应的dp table(dp数组)保持初始值(0)就可以了

动规五部曲:

1)确定dp数组(dp table)以及下标的含义

dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

2)确定递推公式

递推公式和62.不同路径一样,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。

但需要注意一点,因为有了障碍,(i, j)如果就是障碍的话应该就保持初始状态(初始状态为0)

if (obstacleGrid[i][j] == 0) { // 当(i, j)没有障碍的时候,再推导dp[i][j]dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}

3)dp数组如何初始化

在62.不同路径 (opens new window)不同路径中我们给出如下的初始化:

vector<vector<int>> dp(m, vector<int>(n, 0)); // 初始值为0
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;

因为从(0, 0)的位置到(i, 0)的路径只有一条,所以dp[i][0]一定为1,dp[0][j]也同理。

但如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。

如图:

63.不同路径II

下标(0, j)的初始化情况同理。

所以本题初始化代码为:

vector<vector<int>> dp(m, vector<int>(n, 0));
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;

注意代码里for循环的终止条件,一旦遇到obstacleGrid[i][0] == 1的情况就停止dp[i][0]的赋值1的操作,dp[0][j]同理

4)确定遍历顺序

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][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];}
}

5)举例推导dp数组

拿示例1来举例如题:

63.不同路径II1

对应的dp table 如图:

63.不同路径II2

如果这个图看不懂,建议再理解一下递归公式,然后照着文章中说的遍历顺序,自己推导一下!

动规五部分分析完毕,对应C++代码如下:

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) //如果在起点或终点出现了障碍,直接返回0return 0;vector<vector<int>> dp(m, vector<int>(n, 0));for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) 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];}
};
  • 时间复杂度:O(n × m),n、m 分别为obstacleGrid 长度和宽度
  • 空间复杂度:O(n × m)

同样给出空间优化版本:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {if (obstacleGrid[0][0] == 1)return 0;vector<int> dp(obstacleGrid[0].size());for (int j = 0; j < dp.size(); ++j)if (obstacleGrid[0][j] == 1)dp[j] = 0;else if (j == 0)dp[j] = 1;elsedp[j] = dp[j-1];for (int i = 1; i < obstacleGrid.size(); ++i)for (int j = 0; j < dp.size(); ++j){if (obstacleGrid[i][j] == 1)dp[j] = 0;else if (j != 0)dp[j] = dp[j] + dp[j-1];}return dp.back();}
};
  • 时间复杂度:O(n × m),n、m 分别为obstacleGrid 长度和宽度
  • 空间复杂度:O(m)
http://www.khdw.cn/news/65631.html

相关文章:

  • 镇江vi设计青岛网络工程优化
  • 一个做外汇的网站叫熊猫什么的百度的网址是什么呢
  • 网站建设流程有哪些电子制作网站
  • 设计名字嘉兴seo计费管理
  • 网站地图在线生成seo网站排名优化工具
  • 网站建设费用报价单如何让百度收录自己的网站
  • 网站建设 前端 后端哪里有专业的培训机构
  • 武汉建设职业学校seo实战优化
  • 自己做音乐网站挣钱吗百度识图网页版
  • 织梦做分类信息网站seo诊断方法步骤
  • 做网站一个人可以吗广州白云区最新信息
  • mysql做wp网站渠道推广有哪些方式
  • 黄冈最专业的公司网站建设平台爱网站查询挖掘工具
  • 现在电商做的设计用的什么网站成都网站搭建优化推广
  • 微网站建设难不难网络营销推广要求
  • 长春做网站设计手机上可以创建网站吗
  • 公司自己做网站多少费用百度指数分析平台
  • 青岛做门户网站公司seo什么意思中文意思
  • 做的比较好的冷柜网站有哪些佛山网络推广哪里好
  • 微商城有哪些平台家居seo整站优化方案
  • 淘宝网站咋做搜索引擎广告案例
  • 中国商标注册查询官网seo策略工具
  • 装修平台网站制作工具大全
  • 怎么做五个页面网站百度经验官网首页
  • 编写app用什么软件seo刷关键词排名软件
  • 个人可以做新闻网站吗百度搜索收录入口
  • 在线生成网站地图seo文案范例
  • 贵州省建设厅网站官网班级优化大师官网登录
  • 一般购物网站怎么做推广东莞网站推广行者seo08
  • 做游戏直播那个网站好百度推广开户费用多少