1163. 按字典序排在最后的子串
题目描述
给你一个字符串 s
,找出它的所有子串并按字典序排列,返回排在最后的那个子串。
示例 1:
输入:s = "abab" 输出:"bab" 解释:我们可以找出 7 个子串 ["a", "ab", "aba", "abab", "b", "ba", "bab"]。按字典序排在最后的子串是 "bab"。
示例 2:
输入:s = "leetcode" 输出:"tcode"
提示:
1 <= s.length <= 4 * 105
s
仅含有小写英文字符。
解法
方法一:双指针
我们注意到,如果一个子串从位置 $i$ 开始,那么字典序最大的子串一定是 $s[i,..n-1]$,即从位置 $i$ 开始的最长后缀。因此,我们只需要找出字典序最大的后缀子串即可。
我们使用双指针 $i$ 和 $j$,其中指针 $i$ 指向当前字典序最大的子串的起始位置,指针 $j$ 指向当前考虑的子串的起始位置。另外,用一个变量 $k$ 记录当前比较到的位置。初始时 $i = 0$, $j=1$, $k=0$。
每一次,我们比较 $s[i+k]$ 和 $s[j+k]$:
如果 $s[i + k] = s[j + k]$,说明 $s[i,..i+k]$ 和 $s[j,..j+k]$ 相同,我们将 $k$ 加 $1$,继续比较 $s[i+k]$ 和 $s[j+k]$;
如果 $s[i + k] \lt s[j + k]$,说明 $s[j,..j+k]$ 的字典序更大。此时,我们更新 $i = i + k + 1$,并将 $k$ 重置为 $0$。如果此时 $i \geq j$,那么我们将指针 $j$ 更新为 $i + 1$,即 $j = i + 1$。这里我们跳过了以 $s[i,..,i+k]$ 为起始位置的所有后缀子串,因为它们的字典序一定小于对应的 $s[j,..,j+k]$ 为起始位置的后缀子串。
同理,如果 $s[i + k] \gt s[j + k]$,说明 $s[i,..,i+k]$ 的字典序更大。此时,我们更新 $j = j + k + 1$,并将 $k$ 重置为 $0$。这里我们跳过了以 $s[j,..,j+k]$ 为起始位置的所有后缀子串,因为它们的字典序一定小于对应的 $s[i,..,i+k]$ 为起始位置的后缀子串。
最后,我们返回以 $i$ 为起始位置的后缀子串即可,即 $s[i,..,n-1]$。
时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|