
1. 删除字符串的相邻的重复项
题目链接
这道题可以利用我们的模拟哈希表
如果当前元素已经出现过了我们就直接跳过,否则我们就加入
我们可以使用一个字符串去模拟这个过程,当我遍历原先字符串的时候,我们可以去检查当前要添加的字符之前是否已经出现
如果出现了,我们就把当前拼接的字符删除,否则我们就正常拼接
class Solution {
public String removeDuplicates(String s) {
StringBuilder str = new StringBuilder();
char [] ss = s.toCharArray();
for(char ch : ss){
if(str.length() > 0 && ch == str.charAt(str.length()-1)){
str.deleteCharAt(str.length()-1);
}else{
str.append(ch);
}
}
return str.toString();
}
}
2. 比较含退格键的字符
题目链接
这一题还是可以利用刚刚到思想,我们定义两个字符串去模拟栈的过程
遇到退格符就把栈顶元素删除,如果本身字符串就是空的,使用退格符是无效的
class Solution {
public boolean backspaceCompare(String s, String t) {
char [] ss = s.toCharArray();
char [] tt = t.toCharArray();
StringBuilder str1 = new StringBuilder();
StringBuilder str2 = new StringBuilder();
for(char ch : ss){
if(str1.length() > 0 && ch == '#'){
str1.deleteCharAt(str1.length()-1);
}else{
//如果字符串本身就是空的,没必要再让#进来
if(ch == '#'){
continue;
}
str1.append(ch);
}
}
for(char ch : tt){
if(str2.length() > 0 && ch == '#'){
str2.deleteCharAt(str2.length()-1);
}else{
//如果字符串本身就是空的,没必要再让#进来
if(ch == '#'){
continue;
}
str2.append(ch);
}
}
return str1.toString().equals(str2.toString());
}
}
3. 验证出栈顺序
题目链接
这个之前讲过了,这里不再重复赘述
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>();
int pos = 0;
for(int x:pushed){
//先放元素后判断,这样可以直接让栈顶元素和poped中的元素进行比较
stack.push(x);
while(!stack.isEmpty() && stack.peek() == popped[pos]){
stack.pop();
pos++;
}
}
return stack.isEmpty();
}
}
4. 基本计算器II
题目链接
这个题就很有意思了,这题本质上要使用两个栈去模拟,一个栈存数字,一个栈存运算符
但是这一题我们可以使用一个栈存数字,一个字符类型遍历表示当前的运算符去实现
我们指针去遍历字符串的时候,如果当前碰到了一个数,如果一个多位数。不要忘记要把多位数提取出来
如果遍历到当前数,操作符是+,我们就正常放入元素,如果是-,我们则要放入相反数
如果遇到/或者是*,则要进行计算,把结果放入
我们把最开始操作符初始化成+
接下来我们来去模拟这个过程

class Solution {
public int calculate(String s) {
Stack<Integer> stack = new Stack<>();
char [] ss = s.toCharArray();
char op = '+';
int pos = 0;
while(pos < ss.length){
while(pos < ss.length && ss[pos] == ' '){
pos++;
}
int temp = 0;
while(pos < ss.length && !isOp(ss[pos]) && ss[pos] != ' '){
//可能会遇到这种情况:2 _ _ ,如果我们不加ss[pos] != ' ',_ 表示' '
//编译器会误以为_ _ 也是数字,导致计算错误
temp = temp*10+(ss[pos]-'0');
pos++;
}
if(op == '+'){
stack.push(temp);
}else if(op == '-'){
stack.push(-temp);
}else if(op == '*'){
stack.push(stack.pop()*temp);
}else if(op == '/'){
stack.push(stack.pop()/temp);
}
if(pos >= ss.length){
break;
}
op = ss[pos];
pos++;
}
int ret = 0;
while(!stack.isEmpty()){
ret += stack.pop();
}
return ret;
}
private boolean isOp(char ch){
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
}
5. 字符串解码
题目链接
这题的核心就是如果存在多组[],我们就需要找到最里面的一层[],然后逐层解码
我们如果遇到第一个],我们就可以开始解码了
我们可以定义两个栈,一个栈用来存数字,表示需要重复的字符次数
一个栈用来存每一层解码后的字符串
我们以一个具体的实例来说


class Solution {
public String decodeString(String s) {
Stack<Integer> stackNum = new Stack<>();
Stack<String> stackStr = new Stack<>();
stackStr.push("");
char [] ss = s.toCharArray();
int pos = 0;
while(pos < ss.length){
if(isDigit(ss[pos])){
int temp = 0;
while(pos < ss.length && isDigit(ss[pos])){
temp = temp*10+(ss[pos]-'0');
pos++;
}
stackNum.push(temp);
}else if(ss[pos] == '['){
pos++;
StringBuilder str = new StringBuilder();
while(pos < ss.length && ss[pos] >= 'a' && ss[pos] <= 'z'){
str.append(ss[pos]);
pos++;
}
stackStr.push(str.toString());
}else if(ss[pos] == ']'){
int num = stackNum.pop();
String puzzle = stackStr.pop();
StringBuilder tmp = new StringBuilder();
while(num > 0){
tmp.append(puzzle);
num--;
}
StringBuilder popS = new StringBuilder(stackStr.pop());
popS.append(tmp);
stackStr.push(popS.toString());
pos++;
}else{
StringBuilder str = new StringBuilder();
while(pos < ss.length && ss[pos] >='a' && ss[pos] <='z'){
str.append(ss[pos]);
pos++;
}
StringBuilder popS = new StringBuilder(stackStr.pop());
popS.append(str);
stackStr.push(popS.toString());
}
}
return stackStr.pop();
}
private boolean isDigit(char ch){
int num = ch-'0';
return num >= 0 && num < 10;//>=0 应对100[leetcode]这个例子
}
}
当然,我的代码复杂了,你也可以简化代码,我这这个只是便于展示图中思想
913

被折叠的 条评论
为什么被折叠?



