按字典序排在最后的子串

给你一个字符串 s ,找出它的所有子串并按字典序排列,返回排在最后的那个子串

1. 暴力截取比较(超时)

记录最大字符位置,暴力截取比较
class Solution {
public:
    string lastSubstring(string s) {
        map<char, vector<int>> m;
        char mx = 'a';
        for(int i=0;i<s.size();i++){
            if(s[i]>mx) mx = s[i];
            m[s[i]].push_back(i);
        }
        if(mx=='a') return s;
        string res = "";
        for(int i=0;i<m[mx].size();i++){
            string cur = s.substr(m[mx][i]);
            if(cur>res) res = cur;
        }
        return res;
    }
};

2. 双队列逐位比较(超时)

暴力截取的优化,重复筛选当前位置,下一位置
class Solution {
public:
    string lastSubstring(string s) {
        int n = s.size();
        map<char, queue<int>> m;
        char mx = 'a';
        for(int i=0;i<n;i++){
            if(s[i]>mx) mx = s[i];
            m[s[i]].push(i);
        }
        if(mx=='a') return s;
        queue<int> & filter1 = m[mx];
        queue<int> filter2;
        int index = -1;//找最后的index
        int times = 0;
        while(filter1.size()!=1){
            int n1 = filter1.size();
            mx = 'a';
            for(int i=0;i<n1;i++){//第一次筛选下一位置
                int idx = filter1.front();
                filter1.pop();
                if(idx+1==n) continue;
                if(s[idx+1]>mx) mx = s[idx+1];
                filter2.push(idx+1);
            }
            int n2 = filter2.size();
            for(int i=0;i<n2;i++){//把当前最大值的坐标还回去
                int idx = filter2.front();
                filter2.pop();
                if(s[idx]==mx) filter1.push(idx);
            }
            times++;
        }
        return s.substr(filter1.front()-times);
    }
};

3. 双指针

比较失效后,可以直接跳过比较过的位置

class Solution {
public:
    string lastSubstring(string s) {
        int left = 0, right = 1, n = s.size();//双指针
        while (right < n) {
            int step = 0;//当前比较轮次
            while (right + step < n && s[left + step] == s[right + step]) 
                step++;//相等后移比较
            if (right + step < n && s[left + step] < s[right + step]) {//如果是左边的小
                int t = left;
                left = right;//左指针移动到右指针位置
                right = max(right + 1, t + step + 1);//右指针移动到比较失效的下一位
            }
             else  right = right + step + 1;//右指针移动到比较失效的下一位
            
        }
        return s.substr(left);
    }
};

posted @ 2023-04-24 01:44  失控D大白兔  阅读(16)  评论(0编辑  收藏  举报