题目
解题思路
基本问题:字符串中去除哪一个位置的字符,使得字符串成为只去除一个字符情况下的最小子串?
基本思路:依次比较两个字符,删除大的字符,如果一样大,则后移一位接着两两判断;重复以上操作,(1)如果两个字符不相等,则必定有一个更大,删除大的,结束;(2)如果两个字符相等,一直后移到最后了也依然相等,则只需要丢掉最后一个,结束;
if (s.length() == 1) {
return s;
}
int delPos = -1;
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) > s.charAt(i - 1)) {
delPos = i;
break;
} else if (s.charAt(i) < s.charAt(i - 1)) {
delPos = i - 1;
break;
}
}
// has bigger
if (delPos != - 1) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (i == delPos) {
continue;
}
sb.append(s.charAt(i));
}
return sb.toString();
}// all is equals
else {
return s.substring(0, s.length() - 1 - 1);
}
而本题解题思路就是从以上基本思路中来的,从删一个变成删多个,在上面的情况下每一次要删除或者添加额外需要我们保证唯一可行性和唯一性
唯一可行性:删除的元素,要保证后面还能再找到,也就是不能删掉唯一的元素
唯一性:添加的元素不能重复
正解代码
class Solution {
public String smallestSubsequence(String s) {
// simple judge
if (s.length() == 1) {
return s;
}
// define variable
char[] chars = s.toCharArray();
char[] stack = new char[chars.length];
int[] map = new int[128];
// get the count of unique element in the string
int count = 0;
for (char ch : chars) {
if (map[ch] == 0) {
count++;
map[ch] = 1;
}
}
// recover map
Arrays.fill(map, 0);
int top = -1;
stack[++top] = chars[0];
map[chars[0]] = 1;
for (int i = 1; i < chars.length; i++) {
// stack has curent element, skip
if (map[chars[i]] == 1) {
continue;
}
// cycle update smaller element
while (top != -1 && chars[i] < stack[top]) {
// try push, judge the bigger element has more after the pos
int j;
for (j = i + 1; j < chars.length; j++) {
if (stack[top] == chars[j]) {
break;
}
}
// after do not have the bigger element, keep now, think it bigger than top
if (j == chars.length) {
break;
}
// delete its mark
map[stack[top]] = 0;
// delete it in the stack,
--top;
}
// element bigger than top of stack, push it to stack
stack[++top] = chars[i];
// mark it
map[chars[i]] = 1;
}
return String.valueOf(stack, 0, count);
}
}
优化
无