日拱算法,接着冲,这玩意儿是会有瘾是吧?
题目:
给你一个字符串
s
,找出它的所有子串并按字典序排列,返回排在最后的那个子串。
示例 1: 输入:s = "abab" 输出:"bab" 解释:我们可以找出 7 个子串 ["a", "ab", "aba", "abab", "b", "ba", "bab"]。按字典序排在最后的子串是 "bab"。 示例 2: 输入:s = "leetcode" 输出:"tcode"
题目来源:按字典序排在最后的子串
题解:
这题题干很简洁,比什么兔子问题、果篮问题好理解很多。看题之后,很明显的一个概念需要清楚,那就是:字典序排列!
什么是字典序排列?
字典序是指按照单词出现在字典的顺序进行排序的方法。比如 b 在 a 后面,c 在 b 后面,aba 在 ab 后面;bc 在 bac 后面;
所以问题的关键在于理解:什么样的字符串会在字典序排列更靠后?
我们发现:
当前面一截相同,那么肯定是越长的子串字典序越大;比如 abcdX 必定要大于 abcd;
因此以某个字符 x 开头的子串最大的一定是以 x 所在位置为起点、s 最后一个字符为终点的子串
明白这个后,我们在先找出字典序最大的字符 x ,然后依次找每一个以“x 开头的最大字串”,依次对比大小,取最大值,最后返回结果。
JavaScript 实现:
var lastSubstring = function(s) { // 找出字典序最大的字母:char let arr=new Array(26).fill(0); for(let c of s){ arr[c.charCodeAt()-97]=1; } let char; for(let i=arr.length-1;i>=0;i--){ if(arr[i]>0){ char=String.fromCharCode(i+97); break; } } //由前至后依次找出所有以char开头的最大子串,并取其中字典序最大的子串 let index=-1; let ans = "" while((index=s.indexOf(char,index+1))>=0){ if(s.substr(index)>ans){ ans = s.substr(index); } } return ans; }
以上解法不是最简单的,看到下面这个最简单解法真的会震惊到:
var lastSubstring = function(s) { let ans = "" for(let i=0;i<s.length;i++){ if(s.substr(i)>ans){ ans = s.substr(i); } } return ans; };
直接就是字符串截取,然后用大于符号比较,则可满足条件;
"abcdX">"abcd" //ture
小结:这个题目的难度定义为“困难”,一时感觉茫然,有时候的中等题或简单题比这个要困难很多。。。