双指针:
前提:最大的自字典序字串一定是在尾串,也就是说,一定是从某个字符开始到字符串结尾的字串
暴力求解:挨个比较找出最大的字串,当然存在很多重复比较,所以会超时
非暴力求解:我们在比较时标记好最后比较的位置,那么我们在比较到不相等的字符的时候,在不替换的情况下,我们下次比较是从上一次比较的前一个位置开始
1. 我们寻找的是开头字符最大的一个,如果开头字符相等那么就需要逐个比较接下来的字符,如果相等,直到不相等或者到串尾为止,比较看步骤2
2. 假设遇到两个字串的开头字符相同,那么进入比较(使用双指针)
(1)如果两个字符相同,继续比较下一个
(2)如果现有子串大,那么返回false,不再进行比较,false表示不进行替换
(3)如果新的子串大,返回true,替换掉现有子串
(4)如果到结尾仍未找出不同的字符,则返回false不进行替换,并且比较结束,已找到最大的子串
class Solution {
public:
/*暴力求解会超时:时间复杂度:O(n^2)
非暴力解法:标记最后比较的位置,下次比较从最后比较的位置上一个开始比较
*/
string lastSubstring(string s) {
int n = s.size();
int max_i = 0;
for(int i=0;i<s.size();i++){
int start = i; // 用于标记,如果说前面的都相同则无需再次比较,那么直接进入最后比较的上一个进行比较
if(check(max_i,start,s)){
max_i = i;
}
if(start == s.size()){
break;
}
if(start>i+1){
i = start-2;
}
}
return s.substr(max_i,n-max_i);
}
bool check(int max_i,int& start,string& s){
int st= start;
if(s[max_i]<s[start]){
return true;
}else if(s[max_i] == s[start]){
while(start<s.size()&&max_i<st){
if(s[max_i] == s[start]){
max_i++;
start++;
// path[start] = 1;
continue;
}else if(s[max_i]>s[start]){
return false;
}else{
return true;
}
}
return false;
}else{
return false;
}
}
};