栈
删除字符串中的所有相邻重复项目

题目解析 :就是不断删除字符串中相邻重复项,删除后可能又有新的要删除
解法:使用栈的思想,每次放入元素都要判断与前一个已经存入字符串末尾进行比较,如果相同就删除这个字符串,如果不相同或者没有字符就放入
java
class Solution {
public String removeDuplicates(String s) {
//可以使用数组模拟栈
//如果与最后元素相同就进入,反之就删除
StringBuffer ret = new StringBuffer();
for(char ch : s.toCharArray()){
if(ret.length() == 0 || ret.charAt(ret.length() - 1) != ch){
ret.append(ch);
}else{
ret.deleteCharAt(ret.length()-1);
}
}
return ret.toString();
}
}
比较含退格的字符串

题目解析 :给你两个字符串,就是遇到'#'就会删除前一个字符,通过这个操作后判断两个字符串是否相等即可
解法:和上题目思路一样,使用数组来模拟栈

java
class Solution {
public boolean backspaceCompare(String s, String t) {
return changeStr(s).equals(changeStr(t));
}
public String changeStr(String s){
StringBuffer ret = new StringBuffer();
for(char ch : s.toCharArray()){
if(ch != '#'){
ret.append(ch);
}else{
//进行出栈
if(ret.length() != 0){
ret.deleteCharAt(ret.length()-1);
}
}
}
return ret.toString();
}
}
基本计算器||

题目解析 :给了一个字符串里面有运算符和数字字符,让我们求出里面结果
思路:直接使用栈和一个op变量即可,op存放数字前一个运算符
遍历字符串即可
如果是运算符 ,op 修改即可
反之如果是数num
op = '+' 直接入栈
op = '-' 入栈其相反数
op = '*' 将stack.pop() * num入栈
op = '/'将stack.pop() / num入栈
如果当前字符是空格,直接跳过即可


java
class Solution {
public int calculate(String s) {
char op = '+'; //使用这个表示其字符前面的运算符
Stack<Integer> stack = new Stack<>();
int n = s.length();
char ch[] = s.toCharArray();
int i = 0;
while(i < n){
//处理空格
if(ch[i] == ' '){
i++;
}else if(ch[i] >= '0' && ch[i] <= '9'){
//如果是一个数
//提取出来这个数,这个数不一定是个位数
int tem = 0;
while(i < n && (ch[i] >= '0' && ch[i] <= '9')){
tem = tem*10 + (ch[i] - '0');
i++;
}
//处理这个数
if(op == '+'){
stack.push(tem);
}else if(op == '-'){
stack.push(-tem);
}else if(op == '*'){
//将与栈顶元素运算之后入栈
stack.push(stack.pop() * tem);
}else {
stack.push(stack.pop() / tem);
}
}else{
//更新运算符
op = ch[i];
i++;
}
}
int ret = 0;
//最后直接让栈中所有元素进行相加即可
while(!stack.isEmpty()){
ret += stack.pop();
}
return ret;
}
}
字符串解码

题目解析 :将这个字符串解析出来,数字表示后面[]内需要重复的次数,并且里面[ ] 里面可能嵌套[ ] ,如果嵌套就要先把里面解析出来才可以解析外面
思想 :这里需要记录这段字符重复次数n,和这段字符,并且还要判断何时进行重复操作,因此这里就需要两个栈进行操作,一个栈用来方重复次数
另一个放字符串分为四种情况
1.遇到数
2.遇到'['
3.遇到']'
4.遇到正常字符



java
class Solution {
public String decodeString(String s) {
//直接使用两个栈进行分类讨论即可
Stack<StringBuffer> Strstack = new Stack<>();//字符栈
Stack<Integer> Numstack = new Stack<>();//数字栈
Strstack.push(new StringBuffer(""));//先给栈放入一个空的字符串为了后面拼接
int n = s.length();
int i = 0;
char[] ch = s.toCharArray();
while(i < n){
//1.如果是数字字符
if(ch[i] >= '0' && ch[i] <= '9'){
int tem = 0;
while(i < n &&(ch[i] >= '0' && ch[i] <= '9')){
tem = tem * 10 + (ch[i] - '0');
i++;
}
//放入数字栈中
Numstack.push(tem);
}else if(ch[i] == '['){
//将后面的字符全部提取出来
i++;
StringBuffer ret = new StringBuffer();
while(i < n &&(ch[i] >= 'a' && ch[i] <= 'z')){
ret.append(ch[i]);
i++;
}
Strstack.push(ret);
}else if(ch[i] == ']'){
//解析出来,将这个拼接到栈顶元素后面
int num = (int)Numstack.pop();
StringBuffer str = Strstack.pop();
while(num > 0){
//直接拼接到栈顶元素后面
Strstack.peek().append(str);
num--;
}
i++;
}else{
//遇到单独字符串,直接提取出来拼接到栈顶元素后面即可
StringBuffer ret = new StringBuffer();
while(i < n &&(ch[i] >= 'a' && ch[i] <= 'z')){
ret.append(ch[i]);
i++;
}
Strstack.peek().append(ret);
}
}
return Strstack.pop().toString();
}
}
验证栈序列

题目解析 :因为栈是先入后出,因此这里给出一个入栈顺序,让我们判断这个出栈顺序是否符合栈先入后出要求
思路 :直接使用一个栈用来存放入栈元素,入栈以后就要判断其栈顶元素是否与出栈元素一样,如果一样就进行出栈,判断下一个元素,此时的出栈可能是连续出了多次栈,因此这里出栈要采用循环就这样不断入栈出栈,如果最后栈为空,或者出栈数组遍历完,其就说明出栈顺序是对的
java
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
//直接在进栈之后进行判断栈顶元素与要出的元素是否相同即可
Stack<Integer> stack = new Stack<>();
int i = 0;
int n = popped.length;
for(int x : pushed){
//入栈
stack.push(x);
//判断是否要出栈,此时可能回连续出栈,所以这里是一个循环
while(!stack.isEmpty()&&stack.peek() == popped[i]){
stack.pop();
i++;
}
}
//最后栈为空或者popped遍历完才是正确的出栈序列
if(i == n||stack.isEmpty() ){
return true;
}
return false;
}
}