题目要求:给你一个字符串 s
,找出它的所有子串并按字典序排列,返回排在最后的那个子串。
看到题目第一印象首先是双指针然后我就去嘎嘎解题了。。
class Solution {
public:
string lastSubstring(string s) {
using namespace std;
int pt, ps;
pt = ps = 0;
while (ps < s.size()) {
if (int(s[pt]) < int(s[ps]))
pt = ps;
ps++;
}
string sh;
int j = 0;
while (pt < ps)
sh += s[pt++];
return sh;
}
};
这段代码没有通过,原因是我只找了第一个字母。例如“cacacb”会自动查找到cacacb作为答案,实际上最后一个答案是cb,其字典序更大。因此在双指针上需要添加一个临时指针,并且能让上述基础上进行后一个遍历。因此改进后代码如下:
class Solution {
public:
string lastSubstring(string s) {
using namespace std;
int pt, pd;
pt = pd = 0;
int ps = 1;
while (ps < s.size()) {
if (s[pt + pd] == s[ps + pd])pd++;
else if (s[pt + pd] < s[ps + pd])
{
pt = pt + pd + 1;
ps = pt + 1;
pd = 0;
}
else
{
ps = ps + pd + 1;
pd = 0;
}
}
return s.substr(pt);
}
};
通过了!不过战绩一般般。
执行用时:52 ms, 在所有 C++ 提交中击败了15.00%的用户
内存消耗:18 MB, 在所有 C++ 提交中击败了58.00%的用户
在时间复杂度上还需要改进,后续会学习rmq和后缀数组来改进算法。