1. 题目来源
链接:1392. 最长快乐前缀
2. 题目说明
3. 题目解析
方法一:C++17/14+string_view()应用+巧妙解法
暴力一直会超内存,单纯用 s.substr
会内存超限…还有单纯的截取字符串前后缀进行比较的话也会内存超限…
这时,各种秀操作的大佬就出现在了题解区、评论区,哈哈哈学到了很多小技巧~不知道能记下几个…
来自题解区大佬:无脑比较,C++17赐予我力量!
涉及到一些 API
查了查真的只有一句 WOC
…
参见代码如下:
// 执行用时 :400 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :59 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution
{
public:
string longestPrefix(string s)
{
string_view prefix = s;
string_view suffix = s;
for (int i = s.size() - 1; i > 0; --i)
{
suffix.remove_prefix(1);
prefix.remove_suffix(1);
if (prefix == suffix)
{
return string(prefix);
}
}
return string();
}
};
来自同一大佬的 C++14
写法
class Solution
{
public:
string longestPrefix(string s)
{
auto prefixEnd = s.end();
auto suffixBegin = s.begin();
for (int i = s.size() - 1; i > 0; --i)
{
--prefixEnd;
++suffixBegin;
if (equal(s.begin(), prefixEnd, suffixBegin, s.end()))
{
return string(s.begin(), prefixEnd);
}
}
return string();
}
};
方法二:KMP+巧妙解法
回归正规解法,该题其实就是考察 KMP
算法的 next
数组么。可参考之前的博文:[杂谈] 12. BF、KMP、RK Algorithm 字符串匹配算法。
参见代码如下:
// 执行用时 :48 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :17.8 MB, 在所有 C++ 提交中击败了100.00%的用户
namespace KMP{
vector<int> next;
void build(const string &pattern){
int n = pattern.length();
next.resize(n + 1);
for (int i = 0, j = next[0] = -1; i < n; next[++i] = ++j){
while(~j && pattern[j] != pattern[i]) j = next[j];
}
}
vector<int> match(const string &pattern, const string &text){
vector<int> res;
int n = pattern.length(), m = text.length();
build(pattern);
for (int i = 0, j = 0; i < m; ++i){
while(j > 0 && text[i] != pattern[j]) j = next[j];
if (text[i] == pattern[j]) ++j;
if (j == n) res.push_back(i - n + 1), j = next[j];
}
return res;
}
};
class Solution {
public:
string longestPrefix(string s) {
KMP::build(s);
int n = s.length();
string ans = "";
for (int i = 0; i < KMP::next[n]; i++) ans += s[i];
return ans;
}
};