#leetcode编程日记#583. Delete Operation for Two Strings

来源:互联网 发布:歌词改编软件 编辑:程序博客网 时间:2024/06/06 01:12

题目描述

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.

样例:

Input: "sea", "eat"Output: 2Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".

注意事项:

  1. The length of given words won't exceed 500.
  2. Characters in given words can only be lower-case letters.
解题思路:
这个问题其实是最长公共子序列的变形。子序列不同于子串。
公共子序列的例子:“seat”和"ebt",公共子序列是“et”,"et"不是任一字符串的连续子串,是有顺序的子序列。
这道题,只要最长公共子序列的长度L,再用两个字符串的长度之和减去2*L就可以求出要删减的字(步)数。
最长公共子序列(LCS,Longest Common Subsequence)可以用动态规划来求解。
这道题只需要知道最长公共子序列的长度,而不需要知道子序列长什么样(路径)。

递归思想:
求两字符串Xm={x0, x1,…xm-1}和Yn={y0,y1,…,yn-1}的LCS,
如果xm-1=yn-1,那么只需求得Xm-1和Yn-1的LCS,并在其后添加xm-1(yn-1)即可(上述性质1);
如果xm-1≠yn-1,我们分别求得Xm-1和Y的LCS和Yn-1和X的LCS,并且这两个LCS中较长的一个为X和Y的LCS。

但是,在递归求解的办法中,重复的子问题多,效率低下。
改进:用空间换时间,用数组保存中间状态,方便后面的计算。这就是动态规划(DP)的核心思想了。
用二维数组c[i][j]记录串x1x2⋯xi与y1y2⋯yj的LCS长度,则可得到以下状态转移方程。


代码
class Solution {public:    int minDistance(string word1, string word2) {        return word1.size()+word2.size()-2*minLength(word1,word2);    }    int minLength(string word1, string word2) {        vector<vector<int>> vec(word1.size()+1, vector<int>(word2.size()+1, 0));        for (int i = 1; i <= word1.size(); i++) {            for (int j = 1; j <= word2.size(); j++) {                if (word1[i - 1] == word2[j - 1]) {                    vec[i][j] = vec[i - 1][j - 1] + 1;                }                else {                    vec[i][j] = max(vec[i - 1][j], vec[i][j - 1]);                }            }        }        return vec[word1.size()][word2.size()];    }};

原理参照(递归思想,容易超时):http://www.cnblogs.com/javawebsoa/p/3220049.html
实现参照(动态规划):http://blog.csdn.net/u013074465/article/details/45392687
图片来源:http://blog.csdn.net/u012102306/article/details/53184446



原创粉丝点击