3.31 栈
This commit is contained in:
parent
282edf97ec
commit
67048088ff
72
src/main/java/stack/Calculate.java
Normal file
72
src/main/java/stack/Calculate.java
Normal file
@ -0,0 +1,72 @@
|
||||
package stack;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* 题目: 224. 基本计算器 (calculate)
|
||||
* 描述:给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
|
||||
* 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
|
||||
* s 由数字、'+'、'-'、'('、')'、和 ' ' 组成
|
||||
* s 表示一个有效的表达式
|
||||
* '+' 不能用作一元运算(例如, "+1" 和 "+(2 + 3)" 无效)
|
||||
* '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的)
|
||||
*
|
||||
* 示例 1:
|
||||
输入:s = "(1+(4+5+2)-3)+(6+8)"
|
||||
输出:23
|
||||
|
||||
* 链接:https://leetcode.cn/problems/basic-calculator/
|
||||
*/
|
||||
//困难题,学思路
|
||||
public class Calculate {
|
||||
//1 + (3 - 2) - (6 - (4 + 5)) = 1 + 3 - 2 - 6 + 4 + 5
|
||||
|
||||
/**
|
||||
* 栈是用来管理每一层的符号的。由于括号可以嵌套,所以每一层的计算符号(加号或减号)可能不同。
|
||||
* 我们通过栈来保存每一层的符号,当进入一个新的括号时,将当前符号推入栈中,当退出括号时,弹出栈中的符号,回到上一层的符号。
|
||||
*/
|
||||
public int calculate(String s) {
|
||||
Deque<Integer> st = new ArrayDeque<>(); // 存放每一层的符号,一个括号表示一层
|
||||
int sign = 1; // 值为1或-1,表示当前数的符号
|
||||
st.push(sign); // 最顶层的符号为+1
|
||||
int res = 0; // 结果
|
||||
int number;
|
||||
int n = s.length();
|
||||
int i = 0;
|
||||
char ch;
|
||||
while(i < n){
|
||||
if(Character.isDigit(ch = s.charAt(i))){
|
||||
// 如果为数字,生成数值
|
||||
number = 0;
|
||||
while(i < n && Character.isDigit(ch = s.charAt(i))){
|
||||
number = number * 10 + (ch - '0');
|
||||
i++;
|
||||
}
|
||||
// 累加和,真实数字等于符号乘以数值
|
||||
res += sign * number;
|
||||
}else{
|
||||
if(ch == '+'){
|
||||
sign = st.peek(); // 加号,获取当前层的符号
|
||||
}else if(ch == '-'){
|
||||
sign = -st.peek(); // 减号,获取当前层的相反符号
|
||||
}else if(ch == '('){
|
||||
st.push(sign); // 左括号,进入新一层,将当前层符号入栈
|
||||
}else if(ch == ')'){
|
||||
st.pop(); // 右括号,完成一层的运算,弹出这一层符号
|
||||
}
|
||||
i++; // 索引右移
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// 测试代码
|
||||
public static void main(String[] args) {
|
||||
Calculate solution = new Calculate();
|
||||
String s = "(1+(4+5+2)-3)-(6+8)";
|
||||
System.out.println("输入: " + s);
|
||||
System.out.println("输出: " + solution.calculate(s)); // 输出 23
|
||||
}
|
||||
}
|
77
src/main/java/stack/Calculate2.java
Normal file
77
src/main/java/stack/Calculate2.java
Normal file
@ -0,0 +1,77 @@
|
||||
package stack;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 题目: 227. 基本计算器 II (calculate2)
|
||||
* 描述:给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
|
||||
* 整数除法仅保留整数部分。
|
||||
* 你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。
|
||||
*
|
||||
* 示例 1:
|
||||
输入:s = " 3+5 / 2 "
|
||||
输出:5
|
||||
|
||||
* 链接:https://leetcode.cn/problems/basic-calculator-ii/
|
||||
*/
|
||||
//不会 学下思路
|
||||
public class Calculate2 {
|
||||
/**
|
||||
1. 操作符优先级
|
||||
首先要理解一个重要的点——乘法和除法的优先级高于加法和减法。因此,在计算过程中,需要按照操作符的优先级来处理:
|
||||
|
||||
乘法(*)和除法(/)是 立即计算的,一旦遇到它们,就需要把栈中的前一个数与当前的数字一起计算。
|
||||
加法(+)和减法(-)是 延迟计算的,它们需要在下一步遇到新的操作符时计算 => 最后统一计算栈中的元素之和
|
||||
|
||||
2. 栈的使用
|
||||
栈是用来存储每个数值的,我们将每个数值根据其操作符的类型(加法、减法、乘法或除法)计算后,放入栈中
|
||||
*/
|
||||
//s = " 3+5 / 2 "
|
||||
public int calculate(String s) {
|
||||
Deque<Integer> stack = new ArrayDeque<Integer>();
|
||||
char preSign = '+';
|
||||
int num = 0;
|
||||
int n = s.length();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (Character.isDigit(s.charAt(i))) {
|
||||
num = num * 10 + s.charAt(i) - '0';
|
||||
}
|
||||
if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
|
||||
switch (preSign) {
|
||||
case '+':
|
||||
stack.push(num);
|
||||
break;
|
||||
case '-':
|
||||
stack.push(-num);
|
||||
break;
|
||||
case '*':
|
||||
stack.push(stack.pop() * num);
|
||||
break;
|
||||
default:
|
||||
stack.push(stack.pop() / num);
|
||||
}
|
||||
preSign = s.charAt(i);
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
int ans = 0;
|
||||
while (!stack.isEmpty()) {
|
||||
ans += stack.pop();
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Calculate2 calculator = new Calculate2();
|
||||
|
||||
// 测试用例 1
|
||||
String expression1 = "3+5/2";
|
||||
System.out.println("输入: " + expression1);
|
||||
System.out.println("输出: " + calculator.calculate(expression1)); // 期望输出 5
|
||||
|
||||
// 测试用例 2
|
||||
String expression2 = "3+2*2";
|
||||
System.out.println("输入: " + expression2);
|
||||
System.out.println("输出: " + calculator.calculate(expression2)); // 期望输出 7
|
||||
}
|
||||
}
|
46
src/main/java/stack/DailyTemperatures.java
Normal file
46
src/main/java/stack/DailyTemperatures.java
Normal file
@ -0,0 +1,46 @@
|
||||
package stack;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 题目: 739. 每日温度 (dailyTemperatures)
|
||||
* 描述:给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
|
||||
|
||||
* 示例 1:
|
||||
输入: temperatures = [73,74,75,71,69,72,76,73]
|
||||
输出: [1,1,4,2,1,1,0,0]
|
||||
|
||||
* 链接:https://leetcode.cn/problems/daily-temperatures/
|
||||
*/
|
||||
//第一次做没想到怎么利用栈
|
||||
public class DailyTemperatures {
|
||||
public int[] dailyTemperatures(int[] temperatures) {
|
||||
// 结果数组,初始化为全零
|
||||
int[] result = new int[temperatures.length];
|
||||
|
||||
// 栈,存储温度的下标
|
||||
Deque<Integer> stack = new ArrayDeque<>();
|
||||
|
||||
// 遍历整个温度数组
|
||||
for (int i = 0; i < temperatures.length; i++) {
|
||||
// 当前温度
|
||||
int currentTemperature = temperatures[i];
|
||||
|
||||
// 处理栈中的元素,直到栈为空或者栈顶的温度大于当前温度
|
||||
while (!stack.isEmpty() && temperatures[stack.peek()] < currentTemperature) {
|
||||
// 获取栈顶的下标
|
||||
int prevIndex = stack.pop();
|
||||
|
||||
// 计算当前温度和栈顶温度之间的天数差,并赋值给结果数组
|
||||
result[prevIndex] = i - prevIndex;
|
||||
}
|
||||
|
||||
// 当前下标压入栈
|
||||
stack.push(i);
|
||||
}
|
||||
|
||||
// 返回最终的结果数组
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
package stack;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* 题目: 394. 字符串解码 (decodeString)
|
||||
* 描述:给定一个经过编码的字符串,返回它解码后的字符串。
|
||||
@ -12,8 +17,43 @@ package stack;
|
||||
|
||||
* 链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/
|
||||
*/
|
||||
//不会 有难度!
|
||||
public class DecodeString {
|
||||
//s = "3[a]2[bc]" "3[a2[c]]"
|
||||
public String decodeString(String s) {
|
||||
return "";
|
||||
// 定义两个栈
|
||||
Deque<Integer> countStack = new LinkedList<>();
|
||||
Deque<StringBuilder> stringStack = new LinkedList<>();
|
||||
|
||||
StringBuilder current = new StringBuilder();
|
||||
int k = 0; // 用于保存数字
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char ch = s.charAt(i);
|
||||
if (Character.isDigit(ch)) {
|
||||
// 可能有多位数字,所以需要乘10再加当前数字
|
||||
k = k * 10 + (ch - '0');
|
||||
} else if (ch == '[') {
|
||||
// 遇到左括号,先将当前数字和字符串入栈
|
||||
countStack.push(k);
|
||||
stringStack.push(current);
|
||||
// 重置 k 和 current
|
||||
k = 0;
|
||||
current = new StringBuilder();
|
||||
} else if (ch == ']') {
|
||||
// 当我们遇到 ']' 时,可以从栈中取出上一层的字符串,并将当前解码的部分附加到这个上一层的字符串后面。
|
||||
int count = countStack.pop();
|
||||
StringBuilder decoded = stringStack.pop();
|
||||
// 将当前字符串重复 count 次后追加到上层字符串中
|
||||
for (int j = 0; j < count; j++) {
|
||||
decoded.append(current);
|
||||
}
|
||||
current = decoded;
|
||||
} else {
|
||||
// 普通字符直接追加
|
||||
current.append(ch);
|
||||
}
|
||||
}
|
||||
return current.toString();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user