这个一般是模拟的,在想到使用这个数据结构的情况下,相对来说是比较简单
题目
LC1047. 删除字符串中的所有相邻重复项
这个题目就是类似消消乐:
- 先看看它最后的元素是否和要插入的元素一样
- 如果一样,那么就把原来的元素删除,并且跳过当前这个要插入的元素
- 如果不一样,那么就把这个要插入的元素给插入
由于是看最后的一个元素,这就很自然地想到使用栈这个数据结构
Java
public String removeDuplicates(String s) {
StringBuilder result = new StringBuilder();
// 用 StringBuilder 模拟栈
for (int i = 0; i < s.length(); i++) {
if (result.length() > 0 && result.charAt(result.length() - 1) == s.charAt(i)) {
// 找到相同的元素
result.deleteCharAt(result.length() - 1);
continue;
}
result.append(s.charAt(i));
}
return result.toString();
}LC394. 字符串解码
这个题目是这样解法:
- 看到字符,那么就先存储起来
- 看到左括号,那么开辟一个空间,然后存储起来
- 看到右括号,那么就要先去除内部的元素
由此可见,它元素是后进先出的,因此就要想到使用栈这个数据结构
思路:
- 如果是数字,那么就要计算出来数字
- 如果是左括号,那么把一个新的 String 放入栈中,把计算出来的数字放入对应的栈内,注意要把原来的存储数字这个变量清零
- 如果是字符,那么就要把这个字符添加到栈顶元素的末尾
- 如果是右括号,说明已经遍历完成,弹出栈顶元素,复制,然后尾插到当前的栈顶元素的末尾
Java
public String decodeString(String s) {
Stack<StringBuilder> strStack = new Stack<>(); // 存放字符
Stack<Integer> intStack = new Stack<>(); // 存放复制的长度
strStack.add(new StringBuilder("")); // 处理边界情况,防止为栈空的时候,peek() 出现空指针异常
int num = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '[') {
// 把 num 这个数放进去
intStack.add(num);
strStack.add(new StringBuilder()); // 初始化原来的内容
num = 0;
} else if (ch == ']') {
// 把当前的结果推给 strStack 的堆顶元素
int len = intStack.pop();
StringBuilder strPop = strStack.pop();
StringBuilder result = new StringBuilder();
for (int j = 0; j < len; j++) result.append(strPop); // 复制 strPop
strStack.peek().append(result);
} else if ('0' <= ch && ch <= '9') {
num = num * 10 + ch - '0'; // 添加,需要考虑到非个位数的情况
} else {
// 添加
strStack.peek().append(ch);
}
}
return strStack.peek().toString();
}LC946. 验证栈序列
思路:
- 先看一看要插入的元素是否和当前弹出的元素一样
- 如果不一样,那么再看看当前栈顶的元素是否和要弹出的元素一样
- 如果还是不一样,那就把元素添加到栈中,重复循环
- 在元素都添加完后,处理一下栈中的元素,把该弹出的元素给弹出来
- 最后判断一下栈是否为空,如果不为空,那么就不满足条件
Java
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>();
int poppedIndex = 0, pushedIndex = 0;
while (pushedIndex < pushed.length) {
// 刚好相等,那不需要入栈
if (pushed[pushedIndex] == popped[poppedIndex]) {
poppedIndex++;
pushedIndex++;
continue;
}
// 判断一下是否与栈顶元素是否相等
if (!stack.isEmpty() && stack.peek() == popped[poppedIndex]) {
stack.pop();
poppedIndex++;
} else {
// 不相等,那就相加
if (poppedIndex >= popped.length) return false; // 没有相关的元素了
stack.add(pushed[pushedIndex++]);
}
}
// 处理一下最后的末尾
while (!stack.isEmpty() && stack.pop() == popped[poppedIndex++]);
return stack.isEmpty();
}