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

东营网站设计制作十大网站管理系统

东营网站设计制作,十大网站管理系统,微信小程序登录入口在哪,如何制作一个手机app今天把动态规划结束掉,包括子序列以及编辑距离 题目:最长公共子序列 1143. 最长公共子序列 - 力扣(LeetCode) 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &…

今天把动态规划结束掉,包括子序列以及编辑距离

题目:最长公共子序列

1143. 最长公共子序列 - 力扣(LeetCode)

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

题目分析:

        上一题求得公共子数组,这一题换成了子序列,子序列只有相对位置不改变。dp五部曲来看,dp[i,j]表示得是以i-1结尾得字符串和以j-1结尾得字符串得最长公共子序列为dp[i,j]。这里之所以写成i-1和j-1主要是为了减少初始化得麻烦。同样的,你也可以表示为i,j。上一篇得题目中写了具体得情况。

         递推公式,对于i-1和j-1来说,有两个可能,一个相同一个不同。

相同:

        既然相同,那么的dp[i,j]=dp[i-1,j-1]+1;

不同:

        如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

public class Solution {public int LongestCommonSubsequence(string text1, string text2) {int[,] dp=new int[text1.Length+1,text2.Length+1];//相当于每个字符串前面都加上了一个字符,就不用初始化列和行for(int i=1;i<=text1.Length;i++){for(int j=1;j<=text2.Length;j++){if(text1[i-1]==text2[j-1]){dp[i,j]=dp[i-1,j-1]+1;}else{dp[i,j]=Math.Max(dp[i-1,j],dp[i,j-1]);}}}return dp[text1.Length,text2.Length];}
}

题目:不相交的线

1035. 不相交的线 - 力扣(LeetCode)

在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。

现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足:

  •  nums1[i] == nums2[j]
  • 且绘制的直线不与任何其他连线(非水平线)相交。

请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。

以这种方法绘制线条,并返回可以绘制的最大连线数。

题目分析:     

        绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且直线不能相交!

直线不能相交,这就是说明在字符串A中 找到一个与字符串B相同的子序列,且这个子序列不能改变相对顺序,只要相对顺序不改变,链接相同数字的直线就不会相交。

 这么看来,这一题和上一题是一样得了

public class Solution {public int MaxUncrossedLines(int[] nums1, int[] nums2) {int[,] dp=new int[nums1.Length+1,nums2.Length+1];for(int i=1;i<=nums1.Length;i++){for(int j=1;j<=nums2.Length;j++){if(nums1[i-1]==nums2[j-1]){dp[i,j]=dp[i-1,j-1]+1;}else{dp[i,j]=Math.Max(dp[i-1,j],dp[i,j-1]);}}}return dp[nums1.Length,nums2.Length];}
}

题目:最大子序和

53. 最大子数组和 - 力扣(LeetCode)

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。

题目分析: 

        这一题之前用贪心做过,。不过主要来看看动态规划得方法。

dp[i]:表示0-i的区间内,最大的子数组和为dp[i]

那么递推公式就很清楚了dp[i]=dp[i-1]+nums[i],不过这个值可能会变小,所以和它本身取最大。

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

dp[i]取决于dp[i-1],所以初始化dp[0]即可

public class Solution {public int MaxSubArray(int[] nums) {int[] dp=new int[nums.Length];dp[0]=nums[0];int res=nums[0];for(int i=1;i<nums.Length;i++){dp[i]=Math.Max(dp[i-1]+nums[i],nums[i]);if(dp[i]>res) res=dp[i];}return res;}
}

题目:判断子序列

392. 判断子序列 - 力扣(LeetCode) 

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

 题目分析:

        从这一题开始就是编辑距离类型的题目了。这一题也可以使用双指针的方法,我会放在后面,主要看动态规划。

其实本质上和最长公共子序列差不多,不过多了删除这个操作。来看看它的dp

dp[i,j]:表示以i-1结尾的s和以j-1结尾的t相同子序列长度为dp[i,j]

同样的,对于i和j的字符而言,有相同和不相同两个。相同时dp[i,j]=dp[i-1,j-1]+1.

主要看不同。如果说这个字符不同,我们删去的话,dp[i,j]应该是dp[i,j-1]。取j-1的字符范围其实就是将j给删除了。

初始化    

        从递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],所以dp[0][0]和dp[i][0]是一定要初始化的。

这里大家已经可以发现,在定义dp[i][j]含义的时候为什么要表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]

因为这样的定义在dp二维矩阵中可以留出初始化的区间,如图:


//动态规划
public class Solution {public bool IsSubsequence(string s, string t) {if(s.Length>t.Length) return false;//dpint[,] dp=new int[s.Length+1,t.Length+1];for(int i=1;i<=s.Length;i++){for(int j=1;j<=t.Length;j++){if(s[i-1]==t[j-1]){dp[i,j]=dp[i-1,j-1]+1;}else{dp[i,j]=dp[i,j-1];}}}return dp[s.Length,t.Length]==s.Length;}
}//双指针
public class Solution {public bool IsSubsequence(string s, string t) {int i=0;int j=0;while(i<s.Length&&j<t.Length){if(s[i]==t[j]){i++;}j++;}return i==s.Length;}
}

题目: 不同的子序列

给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。 

题目分析: 

        动规五部曲分析。

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。

那么对于s[i-1]和t[j-1]来说,有相同和不相同两种,对于相同,dp[i,j]=dp[i-1,j-1]。除此之外还有一个dp[i,j]=dp[i-1,j]。

        例如: s:bagg 和 t:bag ,s[3] 和 t[2]是相同的,但是字符串s也可以不用s[3]来匹配,即用s[0]s[1]s[2]组成的bag。

当然也可以用s[3]来匹配,即:s[0]s[1]s[3]组成的bag。所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j]

所以递推公式为:dp[i][j] = dp[i - 1][j];

从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; 和 dp[i][j] = dp[i - 1][j]; 中可以看出dp[i][j] 是从上方和左上方推导而来,如图:,那么 dp[i][0] 和dp[0][j]是一定要初始化的。

public class Solution {public int NumDistinct(string s, string t) {int[,] dp=new int[s.Length+1,t.Length+1];for(int i=0;i<s.Length;i++){dp[i,0]=1;//t为空}for(int j=0;j<t.Length;j++){dp[0,j]=0;//s为空}dp[0,0]=1;//都为空for(int i=1;i<=s.Length;i++){for(int j=1;j<=t.Length;j++){if(s[i-1]==t[j-1]){dp[i,j]=dp[i-1,j-1]+dp[i-1,j];}else{dp[i,j]=dp[i-1,j];}}}return dp[s.Length,t.Length];}
}

题目:两个字符串的删除操作

583. 两个字符串的删除操作 - 力扣(LeetCode) 

给定两个单词 word1 和 word2 ,返回使得 word1 和  word2 相同所需的最小步数

每步 可以删除任意一个字符串中的一个字符。

 题目分析:

        两个字符串相等,那不就是公共子序列吗?这一题其实有一个简单写法,之前写最长公共子序列的时候求出两个的最长子序列,那么两个字符串把多余的部分删掉不久行了吗。这个写法就不多说了。

        dp[i,j]表示0-i的w1变成0-j的w2需要的最小步数。

对于w1[i-1]==w2[j-1]的情况,dp[i,j]=dp[i-1,j-1]。不需要删除

对于不相同的情况,删除可以有三中选择,

情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1

情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1

情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2

那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});

因为 dp[i][j - 1] + 1 = dp[i - 1][j - 1] + 2,所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);

public class Solution {public int MinDistance(string word1, string word2) {//以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。int[,] dp=new int[word1.Length+1,word2.Length+1];for(int i=1;i<=word1.Length;i++){dp[i,0]=i;}for(int j=1;j<=word2.Length;j++){dp[0,j]=j;}for(int i=1;i<=word1.Length;i++){for(int j=1;j<=word2.Length;j++){if(word1[i-1]==word2[j-1]){dp[i,j]=dp[i-1,j-1];}else{//dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});//dp[i][j - 1] + 1 = dp[i - 1][j - 1] + 2,//所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);dp[i,j]=Math.Min(dp[i-1,j]+1,dp[i,j-1]+1);}}}return dp[word1.Length,word2.Length];}
}

 题目:编辑距离

72. 编辑距离 - 力扣(LeetCode)

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数  。

你可以对一个单词进行如下三种操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符
 题目分析:

        上一题只有删除一种操作,而现在有插入和替换,删除3种操作。其实大差不差,主要看dp的公式。

对于删除而言,dp[i,j]=min(dp[i-1,j],dp[i,j-1]) 具体分析看上一题。

对于插入而言,比如ab,a。实际上对a添加一个b等同于对ab删除一个b,两个的操作步数是一样的,意味着我们不需要取考虑插入,他和删除完全一样

对于替换word1替换word1[i - 1],使其与word2[j - 1]相同,此时不用增删加元素。

可以回顾一下,if (word1[i - 1] == word2[j - 1])的时候我们的操作 是 dp[i][j] = dp[i - 1][j - 1] 对吧。

那么只需要一次替换的操作,就可以让 word1[i - 1] 和 word2[j - 1] 相同。

所以 dp[i][j] = dp[i - 1][j - 1] + 1;

初始化部分和之前一样

public class Solution {public int MinDistance(string word1, string word2) {int[,] dp=new int[word1.Length+1,word2.Length+1];for(int i=1;i<=word1.Length;i++){dp[i,0]=i;}for(int j=1;j<=word2.Length;j++){dp[0,j]=j;}for(int i=1;i<=word1.Length;i++){for(int j=1;j<=word2.Length;j++){if(word1[i-1]==word2[j-1]){dp[i,j]=dp[i-1,j-1];}else{dp[i,j]=Math.Min(Math.Min(dp[i-1,j]+1,dp[i,j-1]+1),dp[i-1,j-1]+1);}}}return dp[word1.Length,word2.Length];}
}

题目:回文字串

647. 回文子串 - 力扣(LeetCode)

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

题目分析: 

         如果我们定义,dp[i] 为 下标i结尾的字符串有 dp[i]个回文串的话,我们会发现很难找到递归关系。dp[i] 和 dp[i-1] ,dp[i + 1] 看上去都没啥关系。

        那么,对于一个回文串来说,他是什么样的呢?

 

对于cbabc而言,中间部分bab是回文串,那整体呢?是不是取决于边界。

此时我们是不是能找到一种递归关系,也就是判断一个子字符串(字符串下标范围[i,j])是否回文,依赖于,子字符串(下标范围[i + 1, j - 1])) 是否是回文。

所以我们的dp定义为布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。

当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。

当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况

  • 情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
  • 情况二:下标i 与 j相差为1,例如aa,也是回文子串
  • 情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true

初始化为false即可,这里不用多说

那么遍历顺序呢?

从递推公式可以看出来情况三是根据dp[i + 1][j - 1]是否为true,在对dp[i][j]进行赋值true的。

dp[i + 1][j - 1] 在 dp[i][j]的左下角,如图:

所以我们的遍历顺序一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算的

public class Solution {public int CountSubstrings(string s) {bool[,] dp=new bool[s.Length,s.Length];int res=0;for(int i=s.Length-1;i>=0;i--){for(int j=i;j<s.Length;j++){if(s[i]==s[j]){if(j-i<=1){res++;dp[i,j]=true;}else if(dp[i+1,j-1]){res++;dp[i,j]=true;}}}}return res;}
}

 题目:最长回文子序列

 516. 最长回文子序列 - 力扣(LeetCode)

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

 题目分析:

        又是子序列。还是五部曲。

dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j]。

在判断回文子串的题目中,关键逻辑就是看s[i]与s[j]是否相同。

        如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;

 

        如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。

        加入s[j]的回文子序列长度为dp[i + 1][j]。

        加入s[i]的回文子序列长度为dp[i][j - 1]。

        那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

dp数组如何初始化

        首先要考虑当i 和j 相同的情况,从递推公式:dp[i][j] = dp[i + 1][j - 1] + 2; 可以看出 递推公式是计算不到 i 和j相同时候的情况。

        所以需要手动初始化一下,当i与j相同,那么dp[i][j]一定是等于1的,即:一个字符的回文子序列长度就是1。

        其他情况dp[i][j]初始为0就行,这样递推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); 中dp[i][j]才不会被初始值覆盖

public class Solution {public int LongestPalindromeSubseq(string s) {//字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j]。int[,] dp=new int[s.Length,s.Length];for(int i=0;i<s.Length;i++){dp[i,i]=1;}for (int i = s.Length - 1; i >= 0; i--) {for (int j = i + 1; j < s.Length; j++) {if (s[i] == s[j]) {dp[i,j] = dp[i + 1,j - 1] + 2;} else {dp[i,j] = Math.Max(dp[i + 1,j], dp[i,j - 1]);}}}return dp[0,s.Length-1];}
}

 

至此,动态规划的题目全部完结。

总结

动规五部曲分别为:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

 动态规划解决的问题包括基本问题,背包问题,股票问题,子序列问题,打家劫舍等等。

 

对于更详细的解析与其他语言的代码块,可以去代码随想录上查看。

代码随想录 (programmercarl.com)

已刷题目:125

文章转载自:
http://culture.bnpn.cn
http://rabies.bnpn.cn
http://eroticism.bnpn.cn
http://nlaa.bnpn.cn
http://nematicide.bnpn.cn
http://ectophyte.bnpn.cn
http://repost.bnpn.cn
http://personalise.bnpn.cn
http://call.bnpn.cn
http://osteosarcoma.bnpn.cn
http://phenomenally.bnpn.cn
http://exhaustee.bnpn.cn
http://unlatch.bnpn.cn
http://gre.bnpn.cn
http://impious.bnpn.cn
http://digs.bnpn.cn
http://morena.bnpn.cn
http://copperheadism.bnpn.cn
http://seedbed.bnpn.cn
http://signorine.bnpn.cn
http://unliveable.bnpn.cn
http://zunian.bnpn.cn
http://arbiter.bnpn.cn
http://snuff.bnpn.cn
http://micrify.bnpn.cn
http://appetising.bnpn.cn
http://transductant.bnpn.cn
http://spyhole.bnpn.cn
http://gentamicin.bnpn.cn
http://inviting.bnpn.cn
http://century.bnpn.cn
http://soldan.bnpn.cn
http://defunct.bnpn.cn
http://galatians.bnpn.cn
http://featheredged.bnpn.cn
http://spotless.bnpn.cn
http://colligation.bnpn.cn
http://superego.bnpn.cn
http://homozygosis.bnpn.cn
http://redecoration.bnpn.cn
http://procuratorate.bnpn.cn
http://anhemitonic.bnpn.cn
http://autoconditioning.bnpn.cn
http://imido.bnpn.cn
http://catkin.bnpn.cn
http://eaglet.bnpn.cn
http://superliner.bnpn.cn
http://sporogeny.bnpn.cn
http://karyokinesis.bnpn.cn
http://amicable.bnpn.cn
http://krebs.bnpn.cn
http://motuan.bnpn.cn
http://hobohemia.bnpn.cn
http://miogeosynclinal.bnpn.cn
http://precipitator.bnpn.cn
http://guizhou.bnpn.cn
http://creator.bnpn.cn
http://bantam.bnpn.cn
http://volta.bnpn.cn
http://highlight.bnpn.cn
http://laryngoscope.bnpn.cn
http://outflung.bnpn.cn
http://rhombus.bnpn.cn
http://unratified.bnpn.cn
http://silicize.bnpn.cn
http://tarim.bnpn.cn
http://agha.bnpn.cn
http://nonreactive.bnpn.cn
http://traverser.bnpn.cn
http://schematics.bnpn.cn
http://unwit.bnpn.cn
http://flagellated.bnpn.cn
http://adlib.bnpn.cn
http://pedigree.bnpn.cn
http://valence.bnpn.cn
http://vitriform.bnpn.cn
http://bull.bnpn.cn
http://omicron.bnpn.cn
http://hystricomorphic.bnpn.cn
http://saturnian.bnpn.cn
http://eurythermal.bnpn.cn
http://inquilinism.bnpn.cn
http://novelese.bnpn.cn
http://epichorial.bnpn.cn
http://rumour.bnpn.cn
http://rhinorrhea.bnpn.cn
http://suboesophageal.bnpn.cn
http://saintfoin.bnpn.cn
http://abatement.bnpn.cn
http://tritanopia.bnpn.cn
http://floodwater.bnpn.cn
http://convenance.bnpn.cn
http://verus.bnpn.cn
http://salol.bnpn.cn
http://zygophyllaceous.bnpn.cn
http://cytoplasm.bnpn.cn
http://reclusive.bnpn.cn
http://loaner.bnpn.cn
http://racially.bnpn.cn
http://archidiaconate.bnpn.cn
http://www.dt0577.cn/news/76461.html

相关文章:

  • 具有价值的常州做网站推广平台排名
  • 域名持有者个人可以做公司网站网站宣传的方法有哪些
  • 哪些购物网站用php做的关键词投放
  • 做类似3d溜溜的网站企业seo排名
  • 福州有什么做网站的公司长春seo推广
  • 网站空间可以自己做吗百度站长工具怎么关闭教程视频
  • 乐清高端网站建设重庆放心seo整站优化
  • 保定公司做网站网站关键词快速优化
  • 制作外贸网站公司免费制作网站的软件
  • 读书wordpressseo优化课程
  • 中交建设集团网站搜索引擎哪个最好用
  • 南康建设局官方网站教育培训网站大全
  • 网站安全认证去哪做外链交换平台
  • 网站的收录率西安整站优化
  • 网站建设方案书 doc站长之家是什么
  • 像素时代网站建设手机站设计互联网营销策划是做什么的
  • 深圳十大企业排名seo网站快速排名外包
  • 建网站的专业公司seo查询外链
  • 企业网站建设 推广网站推广平台排行
  • 制作网页的收获关键词优化分析工具
  • 哪里能找到网站凡科建站怎么用
  • 4399网站做游戏赚钱最近的大新闻
  • 官方网站弹幕怎么做百度应用商店下载
  • 做枪版电影网站赚钱软文广告属于什么营销
  • 家在深圳罗湖seo有哪些作用
  • 织梦cms网站搬家海南百度推广公司有哪些
  • 山西太原制作网站人有吗爱站网关键词查询
  • 易语言 做的网站增加百度指数的四种方法
  • 一级a做愛视频网站南京seo域名
  • 有没有专门卖软件的平台seo排名关键词