定制您的专属建站方案,旅游网站设计与制作课程设计,东莞企业黄页资料,网站开发与管理专业的就业信息目录
讀題
583. 两个字符串的删除操作
自己看到题目的第一想法
看完代码随想录之后的想法
72. 编辑距离
看完代码随想录之后的想法
583. 两个字符串的删除操作 - 實作
思路
代碼隨想錄思路
Code
72. 编辑距离 - 實作
思路
Code
编辑距离总结篇
判斷子序列
不同…目录
讀題
583. 两个字符串的删除操作
自己看到题目的第一想法
看完代码随想录之后的想法
72. 编辑距离
看完代码随想录之后的想法
583. 两个字符串的删除操作 - 實作
思路
代碼隨想錄思路
Code
72. 编辑距离 - 實作
思路
Code
编辑距离总结篇
判斷子序列
不同的子序列
兩個字符串的刪除操作
編輯距離
總結
判斷子序列
不同子序列
兩個字符串的刪除操作
編輯距離 讀題
583. 两个字符串的删除操作
自己看到题目的第一想法
如果今天可以兩個都刪除那在w1[i - 1] 以及 w2[j - 1]的狀況下有三種狀況兩者匹配dp[i - 1][j - 1]不使用w1[i - 1]→dp[i - 1][j] 不使用w2[j - 1] → dp[i][j - 1]有用畫圖的方式嘗試理解但仍然無法推出狀態的改變。
看完代码随想录之后的想法
看完之後才真正了解自己哪裡錯了首先下標就定義錯了下標應該是dp[i][j] w1[i - 1]為結尾以及w2[j - 1]為結尾如果想要達到相等所需要刪除元素的最少次數為dp[i][j]
根據這個定義如果相等的時候不用刪除元素那就會等於不包含當前i - 1 j - 1的 i - 2 j - 2也就是dp[i][j] dp[i - 1][j - 1]
如果不相等則會有三種狀況可以刪除w1 最少操作次數就是不包含當前的w[i - 1]的狀況也就是dp[i - 1][j] 1 也可以選擇刪除w2 最少操作次數是dp[i][j - 1] 1不包含當前w2[j - 1]的最少狀況。
也可以兩個都刪除也就是dp[i - 1][j - 1] 2但這個我們可以思考為之前的兩種狀況就有包含了如果刪除w1那是取不包含w1[i - 1]的狀況換言之就是刪除w1[i - 1]的狀況是dp[i - 1][j] 在這個基礎上再減去w2[j - 1]這一個數就是dp[i - 1][j] 1。
最後可以簡化為dp[i][j] min(dp[i - 1][j] 1, dp[i][j - 1] 1);
72. 编辑距离
看完代码随想录之后的想法
非常清晰基本上有寫過之前的題目就會知道其中的門道跟上一題一樣先定義好dp[i][j]的定義在下標word1[i - 1]以及下標word2[j-1]使其相同的最小編輯距離為dp[i][j]。
那就一樣會有兩種狀況相同與不相同
相同的話就是dp[i][j] dp[i - 1][j - 1]代表不需要任何操作跟上一次不包含word1[i - 1]以及word2[j - 1]的狀況一致
不相同的話要做增刪換
增和刪可以想成同樣一個操作數都是一樣的引用代碼隨想錄中提到的例子 word2添加一个元素相当于word1删除一个元素例如 word1 ad word2 aword1删除元素d 和 word2添加一个元素d变成word1a, word2ad 最终的操作数是一样 dp数组如下图所示意的 0 a 0 a d---------- ---------------0 | 0 | 1 | 0 | 0 | 1 | 2 |---------- ---------------a | 1 | 0 | a | 1 | 0 | 1 |---------- ---------------d | 2 | 1 |----------替換的話代表只需要替換其中一個數就可以一致那就會是dp[i][j] dp[i - 1][j - 1] 1代表我只要替換word1 或者word2就可以使得兩者相同。使用dp[i - 1][j - 1]的緣故是這個數不包含word1、或word2所以如果只需要替換一個數就可以達成那就是將這個數加一就好 583. 两个字符串的删除操作 - 實作
思路 定義DP數組以及下標的含意 i - 1 下標的word1以及 j - 1 下標的word2要達到相同的子序列最少需要刪除多少次為dp[i][j] 遞推公式 分成兩種狀態相同與不相同 相同的話代表不用刪除也就是dp[i - 1][j - 1]即為上一次不包含當前兩個數的狀況 不相同的話有三種狀況 刪除word1 代表不包含當前word1的狀況在加上一個刪除的個數也就是dp[i - 1][j] 1刪除word2 代表不包含當前word2的狀況再加上1個刪除數也就是dp[i][j - 1] 1刪除word1、word2 代表不包含當前word1、word2的狀況加上兩個刪除數也就是dp[i - 1][j - 1] 2但可以換個角度來看如果刪除word1或word2時我們要先得知不包含word1或word2的狀況也就是dp[i - 1][j] 或 dp[i][j - 1] 也就是說這兩個狀態組都代表已經忽略word1 以及word 2時當前的狀況那在這個基礎上再加1也可以理解為在忽略word1的狀況下在刪除word2 就會是將word1、word2都刪除的狀況也就是dp[i - 1][j] 1。 根據遞推公式、題意以及定義確定DP數組如何初始化 因為兩者都可以刪除所以在初始話時空字符串都是0因為不用刪除其他的部分則根據當前的位置刪除不同數量的word即可以成為空字符串也就是要刪除i 個或j個字字符串才會為空 確定遍歷順序 因為需要左上角的數據來進行遍歷所以是由前往後。
代碼隨想錄思路
Code
class Solution {
public:int minDistance(string word1, string word2) {vectorvectorint dp (word1.size() 1, vectorint(word2.size() 1, 0));for(int i 0; i word1.size(); i) dp[i][0] i;for(int j 0; j word2.size(); j) dp[0][j] j;for(int i 1; i word1.size(); i) {for(int j 1; j word2.size(); 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, dp[i][j - 1] 1);}}return dp[word1.size()][word2.size()];}
};72. 编辑距离 - 實作
思路 定義DP數組以及下標的含意 i - 1 下標的word1以及 j - 1 下標的word2要達到相同的子序列最少需要編輯多少次為dp[i][j] 遞推公式 分成兩種狀態相同與不相同 相同的話代表不用編輯也就是dp[i - 1][j - 1]即為上一次不包含當前兩個數的狀況 不相同的話有三種狀況取最小的 刪除\添加 word1 代表不包含當前word1的狀況在加上一個刪除\添加的個數也就是dp[i - 1][j] 1刪除\添加 word2 代表不包含當前word2的狀況再加上1個刪除\添加數也就是dp[i][j - 1] 1替換 代表不包含當前word1、word2的狀況加上一個操作也就是dp[i - 1][j - 1] 1 根據遞推公式、題意以及定義確定DP數組如何初始化 當j - 1以及 i - 1的word1、word2需要初始化時需要刪除i個或j個字符才會等於空字符 確定遍歷順序 總共有四個遞推公式 dp[i][j] dp[i - 1][j - 1] dp[i][j] dp[i - 1][j - 1] 1 dp[i][j] dp[i - 1][j] 1 dp[i][j] dp[i][j - 1] 1 因為需要左上角的數據來進行遍歷所以是由前往後。
Code
class Solution {
public:int minDistance(string word1, string word2) {vectorvectorint dp (word1.size() 1, vectorint(word2.size() 1));for(int i 0; i word1.size(); i) dp[i][0] i;for(int j 0; j word2.size(); j) dp[0][j] j;for(int i 1; i word1.size(); i) {for(int j 1; j word2.size(); j) {if(word1[i - 1] word2[j - 1]) dp[i][j] dp[i - 1][j - 1];else dp[i][j] min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) 1;}}return dp[word1.size()][word2.size()];}
};编辑距离总结篇
判斷子序列
定義: dp[i][j] 代表 i - 1 的s 和 j - 1 的t 相同子序列的長度為dp[i][j]
根據這個定義我們可以知道當兩者相同時長度要加一
如果不相等時則可以視為忽略當下的t[j - 1]取t的前一個數也就是t[j - 2] → dp[i][j] dp[i][j - 1]
不同的子序列
定義: dp[i][j]: 以i - 1為結尾s子序列當中出現以j - 1為結尾t的個數為dp[i][j]
根據定義 兩者相等時有兩種狀況 我可以使用s[i - 1]也可以不使用s[i - 1] 因為定義是i - 1為結尾的s子序列中出現以j - 1為結尾的t個數 所以在使用s[i - 1]的狀況我不用刪除任何元素所以我的值會是dp[i - 1][j - 1]即上一次的狀況 如果不使用s[i - 1]的狀況我等同於只需要不考慮s[i - 1] 但t[j - 1]仍然在所以值會是dp[i - 1][j] 相同時的轉移方程就會是dp[i][j] dp[i - 1][j - 1] dp[i - 1][j]; 兩者不相等時相當於s 要刪除元素因為 s的字符串中這個位置並沒有t的字串所以要刪除 如果是s要刪除元素那就是取s[i - 2] 這個不包含s[ i -1]的最大值但t是要比較的子序列所以t不用動也就是說這個dp[i][j]會是由s[i - 2]t[j - 1]所組成所對應的dp數組是dp[i][j] dp[i - 1][j]。
初始化:
dp[i][0] 一定都是1因為把s全部刪除後出現空字符的個數就是一
dp[0][j] 因為s無論如何都無法變成t所以都是0
dp[0][0] 空字符串s可以刪除0個元素變成空字符串t,所以等於1
兩個字符串的刪除操作
定義: i - 1 下標的word1以及 j - 1 下標的word2要達到相同的子序列最少需要刪除多少次為dp[i][j]
根據這個定義轉移方程會有兩個狀況
兩者相同
相同的話代表不用刪除也就是dp[i - 1][j - 1]即為上一次不包含當前兩個數的狀況
兩者不相同
不相同的話有三種狀況
刪除word1 代表不包含當前word1的狀況在加上一個刪除的個數也就是dp[i - 1][j] 1刪除word2 代表不包含當前word2的狀況再加上1個刪除數也就是dp[i][j - 1] 1刪除word1、word2 代表要不包含word1以及word2的值也就是dp[i - 1][j - 1] 並加上刪除兩次所以是dp[i - 1][j - 1] 2但也可以想成取word1不存在的部分也就是dp[i - 1][j]並刪除word2也就是dp[i - 1][j] 1反之也可以想成word2不存在。那因為我們要找出最少需要刪除多少次所以就是取刪除狀況中最小的數值1
狀態轉移方程就會是 dp[i][j] min(dp[i - 1][j], dp[i][j - 1]) 1;
初始化的部分就是要如何將i - 1結尾的word1以及j - 1結尾的word2 刪除至空字符串就會需要i, j 次的刪除次數才行。
編輯距離
定義: i - 1 下標的word1以及 j - 1 下標的word2要達到相同的子序列最少需要操作多少次為dp[i][j]
這一題其實就是前面的部分只是要想明白相同時要做甚麼、不相同時要做甚麼
如果相同則不操作
不相同則需要找出最小的增、刪、替換的方案
增加跟刪除可以想成同一個操作數
需要增刪word1時都是取dp[i - 1][j] 1需要增刪word2時都是取dp[i][j - 1] 1至於增刪word1、word2則跟之前一樣可以簡化成上述的兩個式子需要替換word1或word2的話則需要取這兩個都不存在的部分加上一次操作數也就是dp[i - 1][j - 1] 1
所以得出四個轉移方程
if(word1[i - 1] word2[j - 1])
dp[i][j] dp[i - 1][j - 1];
else
dp[i][j] min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) 1;
總結 在編輯距離的題目當中有個很重要的核心就是定義好dp[i][j]的定義在根據這個定義去推導出公式以及初始化的方式
其實前三題很重要的思維就是對於刪除的理解在不同的定義上刪除的做法都不太一樣
判斷子序列
刪除是dp[i][j - 1]忽略前一個t
不同子序列
使用s[i - 1]的我不用刪除任何元素所以值會是dp[i - 1][j - 1]即上一次的狀況
如果不使用s[i - 1]的狀況我等同於只需要不考慮s[i - 1] 但t[j - 1]仍然在所以值會是dp[i - 1][j]
相同時的轉移方程就會是dp[i][j] dp[i - 1][j - 1] dp[i - 1][j];
兩者不相等時相當於s 要刪除元素因為 s的字符串中這個位置並沒有t的字串所以要刪除
如果是s要刪除元素那就是取s[i - 2] 這個不包含s[ i -1]的最大值但t是要比較的子序列所以t不用動也就是說這個dp[i][j]會是由s[i - 2]t[j - 1]所組成所對應的dp數組是dp[i][j] dp[i - 1][j]。
兩個字符串的刪除操作
刪除word1 代表不包含當前word1的狀況在加上一個刪除的個數也就是dp[i - 1][j] 1刪除word2 代表不包含當前word2的狀況再加上1個刪除數也就是dp[i][j - 1] 1刪除word1、word2 代表要不包含word1以及word2的值也就是dp[i - 1][j - 1] 並加上刪除兩次所以是dp[i - 1][j - 1] 2
編輯距離
所謂的增刪基本上是同一個操作數只是需要明確甚麼是替換以及下標定義為何
需要增刪word1時都是取dp[i - 1][j] 1需要增刪word2時都是取dp[i][j - 1] 1需要替換word1或word2的話則需要取這兩個都不存在的部分加上一次操作數也就是dp[i - 1][j - 1] 1
整體而言編輯距離透過這幾天的理解過後透過這次的總結對於這類題目有更深的了解了。