Title:

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character

这题仍可以使用动态规划,问题是,如何得到转移方程。

if a[i] == b[j] then d[i,j] = d[i-1,j-1]

但是不相等的情况下如何计算呢

题目给出了三种可能方式,结果就是根据这三种方式进行

if a[i] != b[j] then min(

a[i-1,j]//相当于删除a[i-1]

a[i,j-1]//相当于插入a的末尾,插入的为b的末尾,这样a,b的末尾相等,所以,要同时减1

a[i-1,j-1]//相当于替换

)

https://blog.csdn.net/zxzxzx0119/article/details/82054807

int minDistance(string word1,string word2){
int m = word1.size();
int n = word2.size();
vector<vector<int> > result(m+,vector<int>(n+));
for (int i = ; i <= m ; i++)
result[i][] = i;
for (int j = ; j <= n ; j++)
result[][j] = j;
for (int i = ; i < m; i++){
for (int j = ; j < n ; j++){
if (word1[i] == word2[j])
result[i+][j+] = result[i][j];
else
result[i+][j+] = min(result[i][j+],min(result[i+][j],result[i][j]) )+; }
}
return result[m][n];
}

其他相关问题:

(1)

最长公共字串(连续)

string a= "abcdef";

string b = "abdef";

可以使用动态规划来解决,使用一个二维数组,状态d[i,j]表示到a[i]和b[j]的最长公共字串,这样问题就是要找出状态转移方程。

如果a[i] = b[j] 那么,d[i,j] = d[i-1,j-1]+1

如果a[i] != b[j] 那么 ,d[i,j] = 0

最后再遍历一下数组,来找出最大的字串。

优化,首先,遍历找出最大字串这一步可以放到计算过程中。

string LCS(string s1, string s2){
int len1 = s1.length();
int len2 = s2.length();
int maxLength = ;
int index = ;
int table[][];
for (int i = ; i < len1+ ; i++)
table[i][] = ;
for (int i = ; i < len2+ ; i++)
table[][i] = ;
for (int i = ; i <= len1 ; i++){
for (int j = ; j <= len2 ; j++){
if (s1[i-] == s2[j-]){
table[i][j] = table[i-][j-] + ;
}else{
table[i][j] = ;
//table[i][j] = (table[i-1][j] > table[i][j-1]) ? table[i-1][j] : table[i][j-1];
}
if (table[i][j] > maxLength ){
maxLength = table[i][j];
index = i;
} }
}
return s1.substr(index-maxLength,maxLength);
}

例外,一般的动态规划的计算空间都可以降低。将二维空间降至一维空间。

降维对于j一般是正序和逆序,关键是看,如果在计算过程中j-1会被提前计算,则要以相反的顺序进行。比如上面,状态转移是

table[i][j] = table[i-1][j-1] + 1;
如果j是从0 到 len2进行,那么table[j-1]就会被先计算,可是从状态转移我们知道,应该在计算table[j]时,这一行的table[j-1]仍是上一行的,所以应该倒过来进行。
string LCS_continue(string s1,string s2){
int len1 = s1.size();
int len2 = s2.size();
vector<int> result(len2+);
int longest = ;
int index = ;
for (int i = ; i < len2+; i++)
result[i] = ;
for (int i = ; i < len1; i++){
for (int j = len2- ; j >=; j--){
if (s1[i] == s2[j]){
cout<<i<<" "<<j<<endl;
result[j+] = result[j]+;
}else{
result[j+] = ;
}
if (result[j+] > longest){
longest = result[j+];
index = j+;
}
}
}
return s2.substr(index-longest,longest);
}

(2)公共最长子序列(非连续)

非连续的状态转移也很容易得到。

d[i,j] = d[i-1,j-1]+1 (a[i] == b[j])

d[i,j] = max(d[i-1,j],d[i,j-1]) (a[i] != b[j])

同样,在降维的时候,j仍是要逆序进行。

int LCS_not_continue(string s1,string s2){
int len1 = s1.size();
int len2 = s2.size();
vector<int> result(len2+);
for (int i = ; i < len2+; i++)
result[i] = ;
for (int i = ; i < len1; i++){
for(int j = len2- ; j >= ; j--){
if (s1[i] == s2[j]){
result[j+] = result[j]+;
}else{
result[j+] = max(result[j],result[j+]);
}
}
}
return result[len2];
}

(3)最长上升子序列

对于一个序列如1,-1,2,-3,4,-5,6,-7,其最长第增子序列为1,2,4,6

定义递推关系:

dp[i]: 以a_i 为末尾的最长上升子序列的长度

dp[i] = max(1,dp[j]+1) (j < i && a[j] < a[i])

#include <iostream>
#include <vector>
using namespace std; class Solution{
public:
int LIS(vector<int> nums){
vector<int> v(nums.size()+,);
v[] = ;
int result = INT_MIN;
for (int i = ; i < nums.size(); i++){
for (int j = ; j < i; j++){
if (nums[j] < nums[i])
v[i+] = max(v[i+],v[j+]+);
}
/*for (int j = 0; j < i+1; j++){
if (j-1 >= 0 && nums[j-1] < nums[i])
v[i+1] = max(v[i+1],v[j]+1);
}*/
result = max(result,v[i+]);
}
return result;
}
};
int main(){
int a[] = {,,,,};
int size = sizeof(a)/sizeof(int);
vector<int> nums(a,a+size);
Solution solution;
cout<<solution.LIS(nums);
system("pause");
}

LeetCode: Edit Distance && 子序列题集的更多相关文章

  1. [LeetCode] Edit Distance 编辑距离

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  2. Leetcode:Edit Distance 解题报告

    Edit Distance Given two words word1 and word2, find the minimum number of steps required to convert  ...

  3. [leetcode]Edit Distance @ Python

    原题地址:https://oj.leetcode.com/problems/edit-distance/ 题意: Given two words word1 and word2, find the m ...

  4. [LeetCode] Edit Distance 字符串变换为另一字符串动态规划

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  5. Leetcode Edit Distance

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  6. [LeetCode] Edit Distance(很好的DP)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  7. LeetCode——Edit Distance

    Question Given two words word1 and word2, find the minimum number of steps required to convert word1 ...

  8. 动态规划小结 - 二维动态规划 - 时间复杂度 O(n*n)的棋盘型,题 [LeetCode] Minimum Path Sum,Unique Paths II,Edit Distance

    引言 二维动态规划中最常见的是棋盘型二维动态规划. 即 func(i, j) 往往只和 func(i-1, j-1), func(i-1, j) 以及 func(i, j-1) 有关 这种情况下,时间 ...

  9. LeetCode One Edit Distance

    原题链接在这里:https://leetcode.com/problems/one-edit-distance/ Given two strings S and T, determine if the ...

随机推荐

  1. jQuery+css+div一些值得注意的常用语句

    一.div页面布局 一个好的页面布局很重要,这会让你写代码的时候层次分明: 以2列左侧固定右侧自适应宽度为例子: 这是HTML代码: <!DOCTYPE html PUBLIC "-/ ...

  2. ios开发之数据存取1-SQLite

    iOS开发中常用的数据存取方式有: XML属性列表-PList NSKeyedArchiver 归档 Preference-偏好设置 SQLite3 Core Data-以面向对象的方式操作数据库SQ ...

  3. java 几种常见的定时器

    今天闲着没事就总结了一下在java中常用的几种定时器. 主要有3种java.util.Timer, ScheduledExecutorService和quartz 一.Timer 举个简单例子.每隔5 ...

  4. sqlplus 远程oracle

    sqlplus dbuser/dbpassword@192.168.0.2/mydb sqlplus try/try@302-4 302-4为本地oralce  net manager 配置的网络名

  5. android C/C++ source files 全局宏定义 .

    \system\core\include\arch\linux-arm AndroidConfig.h * ============================================== ...

  6. 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型

    this.BeginInvoke(() => { this.btnQuery.Enabled = false; //禁用查询 }); 跨线程调用时,编译上面的代码将提示 对于Control.In ...

  7. POJ 1745

    #include <iostream> #define MAXN 10005 using namespace std; int _m[MAXN]; ]; int main() { //fr ...

  8. java基础知识回顾之javaIO类--RandomAccessFile类

    java.io 类 RandomAccessFile java.lang.Object java.io.RandomAccessFile1.该类不是IO流中的子类.2.该类既能读又能写.3.该对象内部 ...

  9. 解决 Ubuntu 开机 Waiting for 60 seconds more for network configuration

    sudo vim /etc/network/interfaces, 将该文件的内容修改为如下:(也就是说删掉其他的什么auto eth0.auto wlan0) auto lo iface lo in ...

  10. 【Linux高频命令专题(14)】nl

    概述 nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样,nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 ...