You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.6 KiB

2 years ago
package class24;
// 本题测试链接 : https://leetcode.com/problems/remove-duplicate-letters/
public class Code06_RemoveDuplicateLettersLessLexi {
// 在str中每种字符都要保留一个让最后的结果字典序最小 ,并返回
public static String removeDuplicateLetters1(String str) {
if (str == null || str.length() < 2) {
return str;
}
int[] map = new int[256];
for (int i = 0; i < str.length(); i++) {
map[str.charAt(i)]++;
}
int minACSIndex = 0;
for (int i = 0; i < str.length(); i++) {
minACSIndex = str.charAt(minACSIndex) > str.charAt(i) ? i : minACSIndex;
if (--map[str.charAt(i)] == 0) {
break;
}
}
// 0...break(之前) minACSIndex
// str[minACSIndex] 剩下的字符串str[minACSIndex+1...] -> 去掉str[minACSIndex]字符 -> s'
// s'...
return String.valueOf(str.charAt(minACSIndex)) + removeDuplicateLetters1(
str.substring(minACSIndex + 1).replaceAll(String.valueOf(str.charAt(minACSIndex)), ""));
}
public static String removeDuplicateLetters2(String s) {
char[] str = s.toCharArray();
// 小写字母ascii码值范围[97~122]所以用长度为26的数组做次数统计
// 如果map[i] > -1则代表ascii码值为i的字符的出现次数
// 如果map[i] == -1则代表ascii码值为i的字符不再考虑
int[] map = new int[26];
for (int i = 0; i < str.length; i++) {
map[str[i] - 'a']++;
}
char[] res = new char[26];
int index = 0;
int L = 0;
int R = 0;
while (R != str.length) {
// 如果当前字符是不再考虑的,直接跳过
// 如果当前字符的出现次数减1之后后面还能出现直接跳过
if (map[str[R] - 'a'] == -1 || --map[str[R] - 'a'] > 0) {
R++;
} else { // 当前字符需要考虑并且之后不会再出现了
// 在str[L..R]上所有需要考虑的字符中找到ascii码最小字符的位置
int pick = -1;
for (int i = L; i <= R; i++) {
if (map[str[i] - 'a'] != -1 && (pick == -1 || str[i] < str[pick])) {
pick = i;
}
}
// 把ascii码最小的字符放到挑选结果中
res[index++] = str[pick];
// 在上一个的for循环中str[L..R]范围上每种字符的出现次数都减少了
// 需要把str[pick + 1..R]上每种字符的出现次数加回来
for (int i = pick + 1; i <= R; i++) {
if (map[str[i] - 'a'] != -1) { // 只增加以后需要考虑字符的次数
map[str[i] - 'a']++;
}
}
// 选出的ascii码最小的字符以后不再考虑了
map[str[pick] - 'a'] = -1;
// 继续在str[pick + 1......]上重复这个过程
L = pick + 1;
R = L;
}
}
return String.valueOf(res, 0, index);
}
}