题目
从前往后遍历,不ok,遇到极端例子超时
具体代码
class Solution {
public String lastSubstring(String s) {
char[] str = s.toCharArray();
int index = str.length-1;
int max = 0;
for(int i=str.length-1;i>=0;i--){
if(str[i]-'a'>max){
index = i;
max = str[i]-'a';
}else if(str[i]-'a'==max){
if(i-1>=0&&str[i]==str[i-1]) continue;//非常关键!!!
int temp = index;
index = i;
max = str[i]-'a';
for(int j=i,k=temp;j<str.length&&k<str.length;j++,k++){
if(str[k]-'a'==str[j]-'a') continue;
if(str[k]-'a'>str[j]-'a'){
index = temp;
max = str[index]-'a';
break;
}else if(str[k]-'a'<str[j]-'a'){
break;
}
}
}
}
return s.substring(index);
}
}
从后往前遍历,OK
具体代码
class Solution {
public String lastSubstring(String s) {
int right = s.length()-1,left = right;
char big = s.charAt(right--);
while(right >= 0){
if(s.charAt(right)>big){
left = right;
big = s.charAt(right);
}
else if(s.charAt(right) == big){
//比较前一个字符是否相同,相同则继续
if(right-1 >= 0 && s.charAt(right-1)==s.charAt(right)){
right--;
continue;
}
//面向测试用例编程……abab,从后往前遍历,此时left=第二个b,right=第一个b,left是最后一个字符,没办法比较后面的字符,所以要加特殊处理。
if(left == s.length()-1){
left = right;
right--;
continue;
}
for(int i = left+1,j = right+1;i < s.length()&&j < s.length();i++,j++ ){
if(s.charAt(i) == s.charAt(j)){
continue;
}
if(s.charAt(i)>s.charAt(j)){
break;
}
if(s.charAt(i)<s.charAt(j)){
left = right;
break;
}
}
}
right--;
}
return s.substring(left);
}
}
时间复杂度:O(N)
空间复杂度:O(1)
变形:删除字母求字典序最小的字符串(来源笔试)
删除字母求字典序最小的字符串。输入 第一行代表字符串,第二行 k 代表要删除字母的个数,k 小于字符串长度。输出字典序最小的字符串。
示例
输入:cacacb
2
输出:aacb
思路:
- 从前往后遍历,若当前字符比后一个字符大,且可删除次数k>0,删除当前字符。若删除次数不够,则保留当前字符(继续遍历,保留后面所有字符)。
- 遍历完后,字符串呈升序状态,前一个字符≤后一个字符,若删除次数k>0,则从字符串末尾开始删除,直到k==0。
具体代码:
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int k = sc.nextInt();
System.out.println(minString(s,k));
}
private static String minString(String s, int k) {
int len = s.length();
LinkedList<Character> list = new LinkedList<>();
for(int i = 0;i < len -1;i++){
if(s.charAt(i) > s.charAt(i+1)){
if(k > 0){
k--;
}else{
list.add(s.charAt(i));
}
}else{
list.add(s.charAt(i));
}
}
list.add(s.charAt(len-1));
while(k > 0){
list.removeLast();
k--;
}
String ss = "";
for(char a: list){
ss += a;
}
return ss;
}
}