Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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
Lines changed: 148 additions & 0 deletions
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+
}
0 Bytes
Binary file not shown.

‎leetcode/greedy_algorithm/best_time_to_buy_and_sell_stock_ii.cpp‎

Lines changed: 13 additions & 4 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /