题目概述
解题思路
我刚看到这题的时候,想到的思路就是把每个字符串当成一个节点,判断两个点之间是否存在联线,然后构建出一个有向图(森林);然后对所有入度为零的节点去求最长的路径。
这个方法实现起来就比较复杂,所以我参考了他人解法:
有个老哥用了动态规划来求解这道题。他用一个一维的数组dp存储以各个元素为链尾时,链的最长长度。我们首先按照字符串的长度,对原始的字符串vector重新排序。然后对第个字符串,我们只需要遍历一下在它之前的字符串(长度不超过它),对那些长度比它少一的串,做一下比较,看下当前串是否是该串的后续串即可。如果是的话,就可以比较&更新dp[i]的值。我先实现了一版这个方法,不过它险些超时。。。它慢的地方或许在于,每次遍历字符串做比较耗时太久,假设字符串平均长度为S,则时间复杂度是O()。
接下来我参考了另一个老哥的思路——它用map来存储这个dp数组,最漂亮的地方在于,它的字符串比较函数是通过hash实现的:只需要对当前的字符串words[i]做拆分,然后每次删去其中的一个字符,得到余下的子串,在hash map里面检查这个子串是否存在,如果存在,则dp[i]检查一下是否需要更新。这时,时间复杂度就是O()。
方法性能
第一种方法的性能:
第二种方法的性能:
示例代码
第一种方法:
class Solution {
public:
static bool cmp(string A, string B)
{
return A.size() < B.size();
}
bool isNeigh(string A, string B)
{
if(A.size() + 1 != B.size())
return false;
int sta = 0, delta = 0;
while(sta + delta < B.size())
{
if(A[sta] == B[sta + delta])
sta++;
else
delta++;
}
return delta == 1 ? true : false;
}
int longestStrChain(vector<string>& words)
{
int len_w = words.size(), max_len = 0;
vector<int> dp(len_w, 1);
sort(words.begin(), words.end(), cmp);
for(int i = 0; i < len_w; ++i)
{
for(int j = 0; j < i; ++j)
{
if(isNeigh(words[j], words[i]))
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
max_len = max(max_len, dp[i]);
}
return max_len;
}
};
第二种方法:
class Solution {
public:
static bool cmp(const string &A, const string &B)
{
return A.size() < B.size();
}
int longestStrChain(vector<string>& words)
{
int len_w = words.size(), max_len = 0;
unordered_map<string, int> Sub;
sort(words.begin(), words.end(), cmp);
for(int i = 0; i < len_w; ++i)
Sub[words[i]] = 1;
for(int i = 0; i < len_w; ++i)
{
string temp_w = words[i];
for( int wi = 0; wi < temp_w.size(); ++wi)
{
string subs = temp_w.substr(0, wi) + temp_w.substr(wi + 1, temp_w.size() - wi);
if(Sub.find(subs) != Sub.end())
{
Sub[temp_w] = max(Sub[temp_w], Sub[subs] + 1);
}
}
max_len = max(max_len, Sub[temp_w]);
}
return max_len;
}
};
这次学到的一个知识点是:如何定义一些常见的容器的比较函数。一种写法就是:
static bool cmp(const type A, const type B)
{
.....;
return xxx;
}
然后在排序时,调用:
sort(a, a + len, cmp);
或者:
priority_queue<type, cmp> test;
另一个点是,解决这种题目常用的思路是动态规划。