之前去美团和滴滴面试都遇见了这道题,当时思路还不是很清晰,后来又想了一下。
public class Study {
public static void main(String[] args) {
System.out.println(removeSpecialChar("bbdfg"));
System.out.println(removeSpecialChar("ghghacbdsfds"));
System.out.println(removeSpecialChar("dfaaabbbcccdfdf"));
}
//去除字符串中的"ac" "b"字符
public static String removeSpecialChar(String str){
if(str==null || str.equals("")) return str;
Stack<Character> s = new Stack<>();
for(int i=0; i<str.length(); ){
char c = str.charAt(i);
if(c == 'b') {
i++;
}
else if(c != 'c'){
s.push(c);
i++;
}else if(c == 'c'){
if(!s.isEmpty() && s.peek()=='a'){
s.pop();
i++;
}else{
s.push(c);
i++;
}
}
}
StringBuilder sb = new StringBuilder();
while(!s.isEmpty()){
sb.append(s.pop());
}
return sb.reverse().toString();
}
}
运行结果:
普通的删除没有什么技巧,换个角度思考,从头开始遍历字符串,当遇见‘c’字符时需要特别注意,因为有可能前一个字符串可能为‘a’,这就需要删除‘ac’,并且删除之后可能又会产生新的‘ac’连串。具体解决办法是可以使用一个栈来保存最终要保留的字符串,遍历原始字符串,当遇见‘c’时,观察栈顶元素是否为‘a’,若是则栈顶出栈,继续遍历,如不是则直接入栈继续遍历,最终代码如上所示,时间复杂度O(n)。在算法中需要考虑之前状态时往往会使用栈结构