ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1163. Last Substring in Lexicographical Order

2022-07-13 13:31:22  阅读:364  来源: 互联网

标签:slow Last fast Substring start 遍历 字符串 Order 指针


Given a string s, return the last substring of s in lexicographical order.

 

Example 1:

Input: s = "abab"
Output: "bab"
Explanation: The substrings are ["a", "ab", "aba", "abab", "b", "ba", "bab"]. The lexicographically maximum substring is "bab".

Example 2:

Input: s = "leetcode"
Output: "tcode"

 

Constraints:

  • 1 <= s.length <= 4 * 105
  • s contains only lowercase English letters.

题目:给定一个字符串,输出最大子字符串。

思路:可以分析得到,最大子字符串一定是此字符串的一个后缀,难点在找字符串的起始点。用两个指针,一个start记录当前最大的起始点,一个i往前遍历找下一个起始点。时间复杂度是难点。分三种情况:

1)如果s[i] < s[start], 很简单,直接往前走就好了i++

2) 如果s[i] > s[start], 也很简单,直接更新start = i;

3) 难点在如果s[i] == s[start]怎么确定两个子字符串哪个大。可以直接比较子字符串大小,但时间复杂度太大了。只能一个一个往后遍历,用两个指针fast和slow将相等的地方都跳过去。这里也分三种情况:

fast先到字符串结尾了,则start, slow指针遍历的子字符串肯定是最大,直接返回
s[fast] < s[slow], 则start位置不动,原子字符串最大,遍历过的地方不需再遍历,更新i值
s[fast] > s[slow], 则start也需要更新到i, 遍历过的地方不需要再遍历,更新i值。
这里有些不好理解,为什么遍历过的地方不需再遍历了。在跳过相等位置的时候有几种情况:

1)相等的字符串很短 ,比i和start距离短,例如zxyabcdzxybcda,zxya...zxyb..., 则其实z后的x和y已经被i遍历过了,也与z比较过了,因此可以肯定的是比z小,指针可以安全的跳到第二个z处和b处。如果是前一字符串大,则start不变,指针i直接跳到fast之后即可。后一字符串大,指针start更新,i需要往后挪一位。

2)相等的字符串很长,比i和start的距离长,例如zabcdzabcdzac, 中间相等的地方可以证明是相同的字符串(具体说是start与i之间的字符串)不停循环组成。如果是前一字符串大,则不需要更新start,将指针i更新到fast之后(因为fast之前肯定不会有比当前字符大的)。如果是后一字符串大,就比较复杂了,说明fast肯定跳到新一轮循环中,而且新一轮循环的字符串不是全部,中间有一个字符变大了,我们没办法确定大的字符有多大,因此指针需要移到这个循环的开始位置重新比较。可以肯定当前slow指针肯定在循环中,为使代码兼容且简洁,指针i移到slow之后。

代码中s[fast] > s[slow]的i指针用 "i=max(i, slow),i++" 来更新,i = i+1即为上述第一种情况时,i = slow+1即为第二种情况。

代码:

class Solution {
public:
    string lastSubstring(string s) {
        int start = 0, i = 1;
        while(i < s.length()){
            if(s[i] > s[start]) start = i;
            else if(s[i] == s[start]){
                int slow = start, fast = i;
                while(fast < s.length() && s[slow] == s[fast]){
                    slow++;
                    fast++;
                }
                if(fast == s.length()) return s.substr(start);
                else if(s[fast] > s[slow]) {
                    start = i; 
                    i = max(i, slow);
                } else i = fast;
            }
            i++;
        }
        return s.substr(start);
    }
};

 

标签:slow,Last,fast,Substring,start,遍历,字符串,Order,指针
来源: https://www.cnblogs.com/boligongzhu/p/16473510.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有