Skip to content

Commit 31fa4e6

Browse files
committed
feat: add evaluate reverse polish notation
1 parent d670e5e commit 31fa4e6

File tree

3 files changed

+161
-4
lines changed

3 files changed

+161
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* @Author: Chacha
3+
* @Date: 2022-04-24 16:01:51
4+
* @Last Modified by: Chacha
5+
* @Last Modified time: 2022-04-24 16:51:35
6+
*/
7+
8+
/**
9+
* 来源:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/solution/
10+
*
11+
* 150. 逆波兰表达式求值
12+
*
13+
* 根据 逆波兰表示法,求表达式的值。
14+
* 有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
15+
* 注意 两个整数之间的除法只保留整数部分。
16+
* 可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
17+
*
18+
* 逆波兰表达式:
19+
* 逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面:
20+
* 1. 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
21+
* 2. 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
22+
*
23+
* 逆波兰表达式主要有以下两个优点:
24+
* 1. 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
25+
* 2. 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
26+
*
27+
*
28+
* 示例 1:
29+
* 输入:tokens = ["2","1","+","3","*"]
30+
* 输出:9
31+
* 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
32+
*
33+
* 示例 2:
34+
* 输入:tokens = ["4","13","5","/","+"]
35+
* 输出:6
36+
* 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
37+
*
38+
* 示例 3:
39+
* 输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
40+
* 输出:22
41+
* 解释:该算式转化为常见的中缀算术表达式为:
42+
* ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
43+
* = ((10 * (6 / (12 * -11))) + 17) + 5
44+
* = ((10 * (6 / -132)) + 17) + 5
45+
* = ((10 * 0) + 17) + 5
46+
* = (0 + 17) + 5
47+
* = 17 + 5
48+
* = 22
49+
*
50+
*
51+
* 提示:
52+
* 1. 1 <= tokens.length <= 10^4
53+
* 2. tokens[i] 是一个算符("+"、"-"、"*" 或 "/"),或是在范围 [-200, 200] 内的一个整数
54+
*
55+
*/
56+
57+
#include <iostream>
58+
#include <vector>
59+
#include <stack>
60+
61+
using namespace std;
62+
63+
class Solution
64+
{
65+
public:
66+
int evalRPN(vector<string> &tokens);
67+
68+
bool isNumber(string &token)
69+
{
70+
return !(token == "+" || token == "-" || token == "*" || token == "/");
71+
}
72+
};
73+
74+
/**
75+
* 方法一:栈
76+
*
77+
* 逆波兰表达式严格遵循「从左到右」的运算。计算逆波兰表达式的值时,使用一个栈存储操作数,从左到右遍历逆波兰表达式,进行如下操作:
78+
* 1. 如果遇到操作数,则将操作数入栈;
79+
* 2. 如果遇到运算符,则将两个操作数出栈,其中先出栈的是右操作数,后出栈的是左操作数,使用运算符对两个操作数进行运算,将运算得到的新操作数入栈。
80+
*
81+
* 整个逆波兰表达式遍历完毕之后,栈内只有一个元素,该元素即为逆波兰表达式的值。
82+
*
83+
* 时间复杂度:O(n),其中 n 是数组 tokens 的长度。需要遍历数组 tokens 一次,计算逆波兰表达式的值。
84+
* 空间复杂度:O(n),其中 n 是数组 tokens 的长度。使用栈存储计算过程中的数,栈内元素个数不会超过逆波兰表达式的长度。
85+
*
86+
*
87+
* 题解:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/solution/ni-bo-lan-biao-da-shi-qiu-zhi-by-leetcod-wue9/
88+
*
89+
*/
90+
int Solution::evalRPN(vector<string> &tokens)
91+
{
92+
stack<int> stk;
93+
int n = tokens.size();
94+
95+
for (int i = 0; i < n; i++)
96+
{
97+
string &token = tokens[i];
98+
99+
if (isNumber(token))
100+
{
101+
stk.push(atoi(token.c_str()));
102+
}
103+
else
104+
{
105+
int num2 = stk.top();
106+
stk.pop();
107+
108+
int num1 = stk.top();
109+
stk.pop();
110+
111+
switch (token[0])
112+
{
113+
case '+':
114+
stk.push(num1 + num2);
115+
break;
116+
117+
case '-':
118+
stk.push(num1 - num2);
119+
break;
120+
121+
case '*':
122+
stk.push(num1 * num2);
123+
break;
124+
125+
case '/':
126+
stk.push(num1 / num2);
127+
break;
128+
129+
default:
130+
break;
131+
}
132+
}
133+
}
134+
135+
return stk.top();
136+
};
137+
138+
int main(int argc, char const *argv[])
139+
{
140+
Solution s;
141+
vector<string> tokens = {'2', '1', '+', '3', '*'};
142+
vector<string> tokens1 = {'10', '6', '9', '3', '+', '-11', '*', '/', '*', '17', '+', '5', '+'};
143+
144+
cout << "tokens = ['2', '1', '+', '3', '*'], 运算结果为: " << s.evalRPN(tokens) << endl;
145+
cout << "tokens = ['10', '6', '9', '3', '+', '-11', '*', '/', '*', '17', '+', '5', '+'], 运算结果为: " << s.evalRPN(tokens1) << endl;
146+
147+
return 0;
148+
}
Binary file not shown.

leetcode/greedy_algorithm/best_time_to_buy_and_sell_stock_ii.cpp

+13-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: Chacha
33
* @Date: 2022-04-23 23:33:43
44
* @Last Modified by: Chacha
5-
* @Last Modified time: 2022-04-23 23:59:19
5+
* @Last Modified time: 2022-04-24 16:46:52
66
*/
77

88
/**
@@ -60,8 +60,15 @@ class Solution
6060
* 此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑。
6161
* 那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。
6262
*
63-
* 时间复杂度:$O(n)
64-
* 空间复杂度:$O(1)
63+
* 如图:
64+
* 股票价格: 7 1 5 3 6 4
65+
* 每天利润: -6 4 -2 3 -2
66+
* 贪心,每天只收集整利润: 4 + 3 = 7
67+
*
68+
* 局部最优:收集每天的正利润,全局最优:求得最大利润。
69+
*
70+
* 时间复杂度:O(n)
71+
* 空间复杂度:O(1)
6572
*
6673
*/
6774
int Solution::maxProfit(vector<int> &prices)
@@ -78,8 +85,10 @@ int main(int argc, char const *argv[])
7885
{
7986
Solution s;
8087
vector<int> prices = {7, 1, 5, 3, 6, 4};
88+
vector<int> prices1 = {1, 2, 3, 4, 5};
8189

82-
cout << "prices = [7,1,5,3,6,4], 最大利润为" << s.maxProfit(prices) << endl;
90+
cout << "prices = [7, 1, 5, 3, 6, 4], 最大利润为" << s.maxProfit(prices) << endl; // 7
91+
cout << "prices = [1, 2, 3, 4, 5], 最大利润为" << s.maxProfit(prices1) << endl; // 4
8392

8493
return 0;
8594
}

0 commit comments

Comments
 (0)