155.最小栈
使用辅助栈的解法,空间复杂度 O ( n ) O(n) O(n)
class MinStack {
Stack<Integer> vals;
Stack<Integer> minVals;
public MinStack() {
vals = new Stack();
minVals = new Stack();
}
public void push(int val) {
vals.push(val);
if(minVals.isEmpty()) minVals.push(val);
else minVals.push(Math.min(val, minVals.peek()));
}
public void pop() {
minVals.pop();
vals.pop();
}
public int top() {
return vals.peek();
}
public int getMin() {
return minVals.peek();
}
}
不实用辅助栈的方法,空间复杂度 O ( 1 ) O(1) O(1)
class MinStack {
Stack<Long> diffs;
long minVal;
public MinStack() {
diffs = new Stack();
}
public void push(int val) {
if(diffs.isEmpty()){
diffs.push(0L);
minVal = val;
}else{
diffs.push((long)val - minVal);
minVal = Math.min(minVal, val);
}
}
public void pop() {
Long temp = diffs.pop();
if(temp < 0) minVal -= temp;
}
public int top() {//top是不能出栈的
return (int)(minVal + Math.max(diffs.peek(), 0));
}
public int getMin() {
return (int)minVal;
}
}
Deque
的peek()
方法获取的是队列的头部节点值,而Stack
的peek()
方法获取的是栈的顶部值!
394字符串解码
辅助栈法
构建辅助栈 stack, 遍历字符串 s 中每个字符 c;
1.当 c 为数字时,将数字字符转化为数字 multi,用于后续倍数计算;
- 当 c 为字母时,在 res 尾部添加 c;
- 当 c 为 [ 时,将当前 multi 和 res 入栈,并分别置空置 0:
- 当 c 为 ] 时,stack 出栈,拼接字符串 res = last_res + cur_multi * res,其中:
last_res是上个 [ 到当前 [ 的字符串,例如 “3[a2[c]]” 中的 a;
cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 “3[a2[c]]” 中的 2。
2.返回字符串 res。
class Solution {
public String decodeString(String s) {
StringBuilder res = new StringBuilder();
int multi = 0;
LinkedList<Integer> stack_multi = new LinkedList<>();
LinkedList<String> stack_res = new LinkedList<>();
for(Character c : s.toCharArray()){
if(c == '['){
stack_multi.addLast(multi);
stack_res.addLast(res.toString());
multi = 0;
res = new StringBuilder();
}else if(c == ']'){
StringBuilder temp = new StringBuilder();
int cur_multi = stack_multi.removeLast();
for(int i = 0; i < cur_multi; i++) temp.append(res);
res = new StringBuilder(stack_res.removeLast() + temp);
}else if(c >= '0' && c <= '9') multi = multi * 10 + Integer.parseInt(c + "");
else res.append(c);
}
return res.toString();
}
}
递归解法
class Solution {
public String decodeString(String s) {
return dfs(s,0)[0];
}
private String[] dfs(String s, int i){
StringBuilder res = new StringBuilder();
int multi = 0;
while(i < s.length()){
if(s.charAt(i) >= '0' && s.charAt(i) <= '9')
multi = multi * 10 + Integer.parseInt(s.charAt(i) + "");
else if(s.charAt(i) == '['){
String[] temp = dfs(s, i + 1);
i = Integer.parseInt(temp[0]);
while(multi > 0) {
res.append(temp[1]);
multi--;
}
}
else if(s.charAt(i) == ']'){
return new String[] { String.valueOf(i), res.toString() };
}else{
res.append(String.valueOf(s.charAt(i)));
}
i++;
}
return new String[] { res.toString() };
}
}
LinkedList
的addLast
和·removeLast()`方法
Integer.parseInt()
方法,将String
类型转化成int
类型。
String.valueOf()
方法,将int
类型转化成String
类型。
739.每日温度
从右至左遍历
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
Deque<Integer> st = new ArrayDeque<>();
for (int i = n - 1; i >= 0; i--) {
int t = temperatures[i];
while ( !st.isEmpty() && t >= temperatures[st.peek()] ) {
st.pop();
}
if ( !st.isEmpty() ) {
res[i] = st.peek() - i;
}
st.push(i);
}
return res;
}
}