字符串-串的最大表示-后缀数组-1163. 按字典序排在最后的子串
作者:互联网
2020-03-13 13:48:05
问题描述:
给你一个字符串 s,找出它的所有子串并按字典序排列,返回排在最后的那个子串。
示例 1:
输入:"abab"
输出:"bab"
解释:我们可以找出 7 个子串 ["a", "ab", "aba", "abab", "b", "ba", "bab"]。按字典序排在最后的子串是 "bab"。
示例 2:
输入:"leetcode"
输出:"tcode"
提示:
1 <= s.length <= 4 * 10^5
s 仅含有小写英文字符。
问题求解:
首先看数据规模,暴力求解是肯定不行的。时间复杂度基本在O(n) / O(nlogn)级别可以通过。
本题有个点非常重要就是最大的子串一定是其后缀,试想如果最大的子串不是后缀,那么往后追加字符必然比它本身大,矛盾。
但是仅仅观察到这一步暴力求解依然只能作出O(n ^ 2)的解,如何更进一步呢?
想到后缀自然就想到后缀数组,如果使用倍增法,可以在O(nlogn)得到解,如果使用DC3/SA-IS可以在O(n)得到解,可行。
另外,本题还可以转化为字符串的最大表示,本质上是一样的。
简单的来说,字符串的最大表示和最小表示类似,就是遇到小的直接跳过即可,采用这种算法可以在O(n)的时间复杂度得到解。
方法一:字符串的最大表示
时间复杂度:O(n)
public String lastSubstring(String s) { int n = s.length(); int i = 0; int j = 1; int k = 0; while (i < n && j < n && k < n) { int diff = s.charAt((i + k) % n) - s.charAt((j + k) % n); if (diff == 0) k++; else { if (diff > 0) j = j + k + 1; else i = i + k + 1; k = 0; if (i == j) j++; } } return s.substring(Math.min(i, j), n); }
方法二:后缀数组-倍增
时间复杂度:O(nlogn)
标签:子串,1163,后缀,复杂度,int,bab,字符串,序排 来源: https://www.cnblogs.com/hyserendipity/p/12486086.html