华电北风吹
日期:2016/2/24
问题描述:
给定两个序列
X=(x1,x2,...,xm)
和
Y=(y1,y2,...,yn)
,求
X
和
子序列:给定一个序列
X=(x1,x2,...,xm)
,若另一个序列
Z=(z1,z2,...,zk)
满足存在一个严格递增的下标序列
i1,i2,...,ik
使得对所有的
j=1,2,...,k
满足
xij=zj
,就称
Z
是
问题解析:
动态规划法图示
参考代码:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
class Solution
{
public:
vector<string> LongestCommanSubArray(string str1,string str2)
{
int m = str1.length();
int n = str2.length();
vector< vector<int>> c(m + 1, vector<int>(n + 1)), b(m + 1, vector<int>(n + 1));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (str1[i] == str2[j])
{
c[i + 1][j + 1] = c[i][j] + 1;
b[i + 1][j + 1] = 0;
}
else
{
if (c[i][j + 1] >= c[i + 1][j])
{
c[i + 1][j + 1] = c[i][j + 1];
b[i + 1][j + 1] = 1;
}
else
{
c[i + 1][j + 1] = c[i + 1][j];
b[i + 1][j + 1] = 2;
}
}
}
}
vector<string> result;
for (int k = n; k > 0; k--)
{
if (c[m][k] == c[m][n])
{
string subresult = "";
int i = m, j = k;
while ((i > 0) && (j > 0))
{
switch (b[i][j])
{
case 0:
subresult.append(1, str1[i - 1]);
i--; j--;
break;
case 1:
i--;
break;
case 2:
j--;
break;
default:
break;
}
}
reverse(subresult.begin(), subresult.end());
result.push_back(subresult);
}
}
return result;
}
};
int main(int argc, _TCHAR* argv[])
{
Solution s;
string s1 = "ABCBDAB", s2 = "BDCABA";
vector<string> result = s.LongestCommanSubArray(s1, s2);
for (auto i : result)
cout << i << endl;
for each (auto i in result)
{
cout << i << endl;
}
getchar();
return 0;
}