力扣高頻|算法面試題彙總(四):堆、棧與隊列
力扣鏈接
目錄:
- 1.最小棧
- 2.數組中的第K個最大元素
- 3.數據流的中位數
- 4.有序矩陣中第K小的元素
- 5.前 K 個高頻元素
- 6.滑動窗口最大值
- 7.基本計算器 II
- 8.扁平化嵌套列表迭代器
- 9.逆波蘭表達式求值
1.最小棧
設計一個支持 push ,pop ,top 操作,並能在常數時間內檢索到最小元素的棧。
push(x) —— 將元素 x 推入棧中。
pop() —— 刪除棧頂的元素。
top() —— 獲取棧頂元素。
getMin() —— 檢索棧中的最小元素。
示例:
輸入:
[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
輸出:
[null,null,null,null,-3,null,0,-2]
解釋:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
pop、top 和 getMin 操作總是在 非空棧 上調用。
C++
class MinStack {
private:
vector<int> nums;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
nums.push_back(x);
}
void pop() {
nums.pop_back();
}
int top() {
return nums[nums.size() - 1];
}
int getMin() {
int min = nums[0];
for(auto num : nums){
if(num < min)
min = num;
}
return min;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
Python
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.nums = []
def push(self, x: int) -> None:
self.nums.append(x)
def pop(self) -> None:
self.nums.pop()
def top(self) -> int:
return self.nums[len(self.nums) - 1]
def getMin(self) -> int:
min = self.nums[0]
for num in self.nums:
if num < min:
min = num
return min
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
2.數組中的第K個最大元素
在未排序的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和 k = 2
輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4
輸出: 4
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。
思路1:
排序後查找。
使用默認排序算法的複雜度:算法的時間複雜度爲 ,空間複雜度爲 。
C++
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
return nums[nums.size() - k];
}
};
Python
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
nums = sorted(nums)
return nums[len(nums) - k]
思路2:
參考官方思路,使用大頂堆,保留k個最大的數。
向大小爲 k 的堆中添加元素的時間複雜度爲,我們將重複該操作 N 次,故總時間複雜度爲 {O}(N \log k)O(Nlogk)。
在 Python 的 heapq
庫中有一個 nlargest
方法,具有同樣的時間複雜度,能將代碼簡化到只有一行。
C++
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int,vector<int>,greater<int>> q;
for(auto it:nums){
q.push(it);
if(q.size()>k) q.pop();
}
return q.top();
}
};
Python
class Solution:
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
return heapq.nlargest(k, nums)[-1]
3.數據流的中位數
中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。
例如,
[2,3,4] 的中位數是 3
[2,3] 的中位數是 (2 + 3) / 2 = 2.5
設計一個支持以下兩種操作的數據結構:
void addNum(int num) - 從數據流中添加一個整數到數據結構中。
double findMedian() - 返回目前所有元素的中位數。
示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
進階:
如果數據流中所有整數都在 0 到 100 範圍內,你將如何優化你的算法?
如果數據流中 99% 的整數都在 0 到 100 範圍內,你將如何優化你的算法?
思路1:
暴力法,每次獲取中位數時就進行排序獲取,超時。
思路2:
使用最大堆和最小堆,參考劍指offer:數據流中的中位數
C++
class MedianFinder {
private:
// 最大堆
vector<int> maxheap;
// 最小堆
vector<int> minheap;
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
int size = maxheap.size() + minheap.size();
// 如果當前數目是偶數個,默認把num放進最小堆
if((size & 1) == 0){
int temp = num;
//如果最大堆不爲空,且輸入的數字小於最大堆的最大值
if(!maxheap.empty() && num < maxheap[0]){
// 把最大的數字拿出來
temp = maxheap[0];
// 再把數字放進最大堆
maxheap[0] = num;
// 重新生成最大堆
make_heap(maxheap.begin(), maxheap.end());
}
// 把元素放進最小堆
minheap.push_back(temp);
// 重新生成最小堆
push_heap(minheap.begin(), minheap.end(), greater<int>());
}else{// 如果當前數目是奇數個,默認把num放進最大堆
int temp = num;
// 如果最小堆不爲空,且輸入的數字大於最小堆的最小值
if(!minheap.empty() && num > minheap[0]){
temp = minheap[0]; // 把最小的數字拿出來
minheap[0] = num; // 把輸入的數字放進最小堆
make_heap(minheap.begin(), minheap.end(), greater<int>());
}
// 把元素放進最大堆
maxheap.push_back(temp);
// 重新生成最大堆
push_heap(maxheap.begin(), maxheap.end());
}
}
double findMedian() {
int size = maxheap.size() + minheap.size();
double res;
if(size & 1){
res = minheap[0];
}else{
res = (maxheap[0] + minheap[0])*0.5;
}
return res;
}
};
很迷,在最後一個測試用例超時了,所以參考官方實現。
class MedianFinder {
priority_queue<int> maxheap; // 最大堆 降序
priority_queue<int, vector<int>, greater<int>> minheap; // 最小堆 升序
public:
// Adds a number into the data structure.
void addNum(int num)
{
maxheap.push(num); // 把數字添加到最大堆中
minheap.push(maxheap.top()); // 把最大堆的最大值放進最小堆中
maxheap.pop(); // 彈出最大堆最大值
// 如果最大堆的元素個數小於最小堆的個數
if (maxheap.size() < minheap.size()) { // maintain size property
maxheap.push(minheap.top()); // 把最小堆的最小值放進最大堆
minheap.pop(); // 彈出最小堆最小值
}
}
// Returns the median of current data stream
double findMedian()
{ // 默認最大堆的元素個數大於最小堆元素個數
return maxheap.size() > minheap.size() ? (double) maxheap.top() : (maxheap.top() + minheap.top()) * 0.5;
}
};
Python
class MedianFinder:
def __init__(self):
"""
initialize your data structure here.
"""
self.minheap = [] # 最小堆
self.maxheap = [] # 最大堆
def addNum(self, num: int) -> None:
# 默認把元素添加到最大堆
heapq.heappush(self.maxheap, (-num, num)) # python默認最小堆,模擬最大堆
# 把最大堆最大值元素給最小堆
heapq.heappush(self.minheap, self.maxheap[0][1])
# 彈出最大堆的最大值
heapq.heappop(self.maxheap)
# 如果最大堆的元素個數少於最小堆數量,把最小堆的最小值給最大堆
if len(self.maxheap) < len(self.minheap):
heapq.heappush(self.maxheap, (-self.minheap[0], self.minheap[0]))
heapq.heappop(self.minheap)
def findMedian(self) -> float:
size = len(self.minheap) + len(self.maxheap)
# 如果是奇數
if size & 1:
return self.maxheap[0][1]
else:
return (self.maxheap[0][1] + self.minheap[0])*0.5
4.有序矩陣中第K小的元素
給定一個 n x n 矩陣,其中每行和每列元素均按升序排序,找到矩陣中第k小的元素。
請注意,它是排序後的第 k 小元素,而不是第 k 個不同的元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
提示:
你可以假設 k 的值永遠是有效的, 1 ≤ k ≤ n2 。
思路1:
使用堆排序,時間複雜度爲,空間複雜度爲。用最大堆保存最小的k個數,堆頂就是第k小的數。由於矩陣大小是有順序的,還可以有優化空間:如果該行元素大於堆頂,則可以直接中斷該循環,因爲不可能還存在比堆頂還小的元素,進入下一個循環。
C++
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
// 創建大頂堆,保存最小的k個元素
priority_queue<int> maxheap;
for(int col = 0; col < matrix[0].size(); ++col)
for(int row = 0; row < matrix.size(); ++row){
if(maxheap.size() < k ){
// 放進元素
maxheap.push(matrix[row][col]);
}else if(maxheap.top() > matrix[row][col]){// 如果矩陣元素小於最大堆的最大值
// 彈出最大值
maxheap.pop();
maxheap.push(matrix[row][col]);
}else{// 矩陣每行是從小到大,則右邊的元素不可能還小於最大堆最大值
break;
}
}
return maxheap.top();
}
};
Python
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
# 最大堆
maxheap = [] # 最大堆
for row in range(len(matrix)):
for col in range(len(matrix[0])):
if len(maxheap) < k:
heapq.heappush(maxheap, (-matrix[row][col], matrix[row][col])) # python默認最小堆,模擬最大堆
elif maxheap[0][1] > matrix[row][col]:
# 彈出最大堆的最大值
heapq.heappop(maxheap)
# 添加元素
heapq.heappush(maxheap, (-matrix[row][col], matrix[row][col]))
else:
break
return maxheap[0][1]
思路2:
二分法。參考思路如下:
首先第k大數一定落在[l, r]中,其中l = matrix[0][0], r = matrix[row - 1][col - 1].
我們二分值域[l, r]
區間,mid = (l + r) >> 1
, 對於mid,檢查矩陣中有多少元素小於等於mid,記個數爲cnt,那麼有:
- 1、如果
cnt < k
, 那麼[l, mid]
中包含矩陣元素個數一定小於k,那麼第k小元素一定不在[l, mid]
中,必定在[mid +1, r]
中,所以更新l = mid + 1
. - 2、否則
cnt >= k
,那麼[l, mid]
中包含矩陣元素個數就大於等於k,即第k小元素一定在[l,mid]
區間中,更新r = mid;
算法時間複雜度爲, 其中n = max(row, col)
,代表矩陣行數和列數的最大值, m代表二分區間的長度,即矩陣最大值和最小值的差。
C++
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int rows = matrix.size();
int cols = matrix[0].size();
// 使用二分法
int low = matrix[0][0];
int high = matrix[rows - 1][cols - 1];
while(low < high){
int mid = low + (high - low)/2;
int count = findCount(matrix, mid);
// 如果比mid小的數字小於k, 說明第k小的數字大於當前mid
if(count < k)
low = mid + 1;
else
high = mid;
}
return low;
}
int findCount(vector<vector<int>>& matrix, int mid){
// 利用矩陣特性從左小角開始查找
int count = 0;
int rows = matrix.size();
int cols = matrix[0].size();
int row = rows-1;
int col = 0;
while( row >= 0 && col <= cols - 1){
if(matrix[row][col] > mid){
// 先減行數
--row;
}else{// 跳過這一列
count += row+1;
// 移動
++col;
}
}
return count;
}
};
Python
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
# 二分法
low = matrix[0][0]
rows = len(matrix)
cols = len(matrix[0])
high = matrix[rows - 1][cols - 1]
while low < high:
mid = low + (high - low)/2
count = self.findCount(matrix , mid)
if count < k:
low = mid + 1
else:
high = mid
return int(low)
def findCount(self, matrix , mid):
rows = len(matrix)
cols = len(matrix[0])
col = 0
row = rows - 1
count = 0
while row >= 0 and col <= cols - 1:
if matrix[row][col] > mid:
row -= 1
else:
count += row + 1
col += 1
return count
5.前 K 個高頻元素
給定一個非空的整數數組,返回其中出現頻率前 k 高的元素。
示例 1:
輸入: nums = [1,1,1,2,2,3], k = 2
輸出: [1,2]
示例 2:
輸入: nums = [1], k = 1
輸出: [1]
提示:
你可以假設給定的 k 總是合理的,且 1 ≤ k ≤ 數組中不相同的元素的個數。
你的算法的時間複雜度必須優於 O(n log n) , n 是數組的大小。
題目數據保證答案唯一,換句話說,數組中前 k 個高頻元素的集合是唯一的。
你可以按任意順序返回答案。
思路:
首先使用哈希表記錄每個數字出現的頻率,解這使用最小堆進行存儲數字出現的頻率,用來保存前k個高頻元素出現的頻率。
C++
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 用哈希表存儲每個id出現的次數
unordered_map<int, int> idCount;
for(auto num : nums){
if(idCount.find(num) == idCount.end())
idCount[num] = 1;
else
++idCount[num];
}
// 使用最小堆來保存出現頻率最高的k個元素
vector<int> minheap;
for(auto x : idCount){
minheap.push_back(x.second);
// 當已建堆的容器範圍內有新的元素插入末尾後,應當調用push_heap將該元素插入堆中。
push_heap(minheap.begin(), minheap.end(), greater<int>());
if(minheap.size() > k){
// 將堆頂(所給範圍的最前面)元素移動到所給範圍的最後,並且將新的最小值置於所給範圍的最前面
pop_heap(minheap.begin(), minheap.end(), greater<int>());
// 彈出最小堆最小的那個元素
minheap.pop_back();
}
}
vector<int> ans;
for(auto x : idCount){
// 在最小堆中招對應的id,以及保證結果不存在這個數字,以免重複記錄
if(find(minheap.begin(), minheap.end(), x.second) != minheap.end() && find(ans.begin(), ans.end(), x.first) == ans.end()){
ans.push_back(x.first);
}
}
return ans;
}
};
Python:
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
idHash = dict()
for num in nums:
if not num in idHash:
idHash[num] = 1
else:
idHash[num] += 1
# 建立最小堆
minheap = []
for key in idHash:
heapq.heappush(minheap, (idHash[key], key))
if len(minheap) > k:
# 彈出
heapq.heappop(minheap)
# 變最小堆
# heapq.heapify(minheap)
ans = []
for value, key in minheap:
ans.append(key)
return ans
6.滑動窗口最大值
給定一個數組 nums,有一個大小爲 k 的滑動窗口從數組的最左側移動到數組的最右側。你只可以看到在滑動窗口內的 k 個數字。滑動窗口每次只向右移動一位。
返回滑動窗口中的最大值。
進階:
你能在線性時間複雜度內解決此題嗎?
示例:
輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
輸出: [3,3,5,5,6,7]
解釋:
滑動窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
1 <= k <= nums.length
這題劍指offer做過,具體思路見劍指offer|解析和答案(C++/Python) (五)上:滑動窗口最大值
C++
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> maxvalue;
// 新建隊列進行保存最大值的索引
deque<int> index;
for(int i = 0; i < k; ++i){
// 確保索引的值是保留的最大值
while(!index.empty() && nums[i]>= nums[index.back()])
index.pop_back();
// 添加索引
index.push_back(i);
}
for(int i = k; i < nums.size(); ++i){
// 添加最大值
maxvalue.push_back(nums[index.front()]);
// 確保索引的值是保留的最大值
while(!index.empty() && nums[i]>= nums[index.back()])
index.pop_back();
// 如果最大值溢出滑動框
if(!index.empty() && index.front() <= (i - k))
index.pop_front();
index.push_back(i);
}
// 加入最後一個值
maxvalue.push_back(nums[index.front()]);
return maxvalue;
}
};
Python
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
maxValue = list()
if len(nums) > 0 and k > 0:
index = []
for i in range(k):
while len(index) > 0 and nums[i] >= nums[index[-1]]:
index.pop()
index.append(i)
for i in range(k, len(nums)):
maxValue.append(nums[index[0]])
while len(index) > 0 and nums[i] >= nums[index[-1]]:
index.pop()
if len(index) > 0 and index[0] <= (i-k):
index.pop(0)
index.append(i)
maxValue.append(nums[index[0]])
return maxValue
7.基本計算器 II
實現一個基本的計算器來計算一個簡單的字符串表達式的值。
字符串表達式僅包含非負整數,+, - ,,/ 四種運算符和空格 。 整數除法僅保留整數部分。
示例 1:
輸入: "3+22"
輸出: 7
示例 2:
輸入: " 3/2 "
輸出: 1
示例 3:
輸入: " 3+5 / 2 "
輸出: 5
說明:
你可以假設所給定的表達式都是有效的。
請不要使用內置的庫函數 eval。
思路:
參考使用棧的方式來保存計算結果。利用棧的方式解決運算優先級的問題 當爲加減時放入棧中 當爲乘除時講棧頂元素與最近獲得一個數進行運算,同時把棧頂元素彈出,放進計算之後的元素。最後把棧的所有元素加起來即可。
C++
class Solution {
public:
int calculate(string s) {
long result = 0;
long num = 0;
// 初始上一個運算符爲加法 上個數字爲0
char op = '+';
char c;
// 用棧來保存結果
vector<int> stack;
for(int i = 0; i < s.length(); ++i){
c = s[i];
if(c >='0'){
// 計算數字
num = num * 10 + c- '0';
}
// 當遇到符號時,或者是到了字符串末尾
if(c < '0' && c != ' '|| i == s.length() -1){
// 此時op是上一次遇到的符號
if(op == '+') stack.push_back(num);
if(op == '-') stack.push_back(-num);
if(op == '*' || op =='/'){
int temp = (op == '*')? stack.back() * num : stack.back()/num;
// 彈出上一個值
stack.pop_back();
// 重新放進計算的結果
stack.push_back(temp);
}
// 獲取當前op符號
op = s[i];
num = 0;
}
}
while(!stack.empty()){
result += stack.back();
stack.pop_back();
}
return result;
}
};
Python
class Solution:
def calculate(self, s: str) -> int:
stack = []
num = 0
res = 0
op = '+'
ops = ['+', '-', '*', '/']
for i in range(len(s)):
# s[i] != ' ' 很重要
if not s[i] in ops and s[i] != ' ':
num = num*10 + int(s[i])
if s[i] in ops and s[i] != ' ' or i == len(s) - 1:
if op == '+':
stack.append(num)
if op == '-':
stack.append(-num)
if op == '*' :
temp = stack[-1]*num
stack.pop()
stack.append(int(temp))
if op == '/':
temp = stack[-1]/num
stack.pop()
stack.append(int(temp))
num = 0
op = s[i]
for num in stack:
res += num
return res
8.扁平化嵌套列表迭代器
扁平化嵌套列表迭代器
給你一個嵌套的整型列表。請你設計一個迭代器,使其能夠遍歷這個整型列表中的所有整數。
列表中的每一項或者爲一個整數,或者是另一個列表。其中列表的元素也可能是整數或是其他列表。
示例 1:
輸入: [[1,1],2,[1,1]]
輸出: [1,1,2,1,1]
解釋: 通過重複調用 next 直到 hasNext 返回 false,next 返回的元素的順序應該是: [1,1,2,1,1]。
示例 2:
輸入: [1,[4,[6]]]
輸出: [1,4,6]
解釋: 通過重複調用 next 直到 hasNext 返回 false,next 返回的元素的順序應該是: [1,4,6]。
這題沒怎麼看明白,先放一下。
C++
class NestedIterator {
private:
stack<NestedInteger> s;
public:
NestedIterator(vector<NestedInteger> &nestedList) {
// 添加元素
for(int i = nestedList.size() - 1; i >= 0; --i)
s.push(nestedList[i]);
}
int next() {
NestedInteger temp = s.top(); // 獲取棧頂元素
s.pop(); // 彈出棧頂
return temp.getInteger();
}
bool hasNext() {
while(!s.empty()){
NestedInteger temp = s.top();
if(temp.isInteger())
return true;
s.pop();
for(int i = temp.getList().size() - 1; i >= 0; --i)
s.push(temp.getList()[i]);
}
return false;
}
};
還有其他思路:C++ 綜合各路大佬的答案
Python:
來自:棧+迭代,5行代碼簡單易理解
class NestedIterator:
def __init__(self, nestedList: [NestedInteger]):
# 對於nestedList中的內容,我們需要從左往右遍歷,
# 但堆棧pop是從右端開始,所以我們壓棧的時候需要將nestedList反轉再壓棧
self.stack = nestedList[::-1]
def next(self) -> int:
# hasNext 函數中已經保證棧頂是integer,所以直接返回pop結果
return self.stack.pop(-1).getInteger()
def hasNext(self) -> bool:
# 對棧頂進行‘剝皮’,如果棧頂是List,把List反轉再依次壓棧,
# 然後再看棧頂,依次循環直到棧頂爲Integer。
# 同時可以處理空的List,類似[[[]],[]]這種test case
while len(self.stack) > 0 and self.stack[-1].isInteger() is False:
self.stack += self.stack.pop().getList()[::-1]
return len(self.stack) > 0
9.逆波蘭表達式求值
根據逆波蘭表示法,求表達式的值。
有效的運算符包括 +, -, , / 。每個運算對象可以是整數,也可以是另一個逆波蘭表達式。
說明:
整數除法只保留整數部分。
給定逆波蘭表達式總是有效的。換句話說,表達式總會得出有效數值且不存在除數爲 0 的情況。
示例 1:
輸入: [“2”, “1”, “+”, “3”, ""]
輸出: 9
解釋: ((2 + 1) * 3) = 9
示例 2:
輸入: [“4”, “13”, “5”, “/”, “+”]
輸出: 6
解釋: (4 + (13 / 5)) = 6
思路:
這個在《大話數據結構上》看到過。使用棧數據結構。規則:從左到右遍歷表達式的每個數字和符號,遇到是數字就進棧,遇到是符號,就將處於棧頂的兩個數字彈出,進行運算,運算結果進錢, 直到最終獲得結果。
舉例後綴表達式:931 - 3*+102 / +
,以下圖片來自《大話數據結構上》:
C++
class Solution {
public:
int evalRPN(vector<string>& tokens) {
// 用棧來存儲數字
vector<int> nums;
for(int i = 0; i < tokens.size(); ++i){
if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){
nums.push_back(stoi(tokens[i]));
}else if(tokens[i] == "+"){
int add1 = nums.back();
nums.pop_back();
int add2 = nums.back();
nums.pop_back();
add2 = add2 + add1;
nums.push_back(add2);
}else if(tokens[i] == "-"){
int sub1 = nums.back();
nums.pop_back();
int sub2 = nums.back();
nums.pop_back();
sub2 = sub2 - sub1;
nums.push_back(sub2);
}else if(tokens[i] == "*"){
int mul1 = nums.back();
nums.pop_back();
int mul2 = nums.back();
nums.pop_back();
mul2 = mul2 * mul1;
nums.push_back(mul2);
}else if(tokens[i] == "/"){
int div1 = nums.back();
nums.pop_back();
int div2 = nums.back();
nums.pop_back();
div2 = div2 / div1;
nums.push_back(div2);
}
}
return nums[0];
}
};
還有範例,很優美:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
if(tokens.size()==0) return 0;
stack<int> s;
int temp=0;
for(int i=0;i<tokens.size();i++){
if(tokens[i][0]<='9'&&tokens[i][0]>='0'||(tokens[i].size()>1&&tokens[i][0]=='-')){
s.push(atoi(tokens[i].c_str()));
}else{
int a=s.top();
s.pop();
int b=s.top();
s.pop();
if(tokens[i][0]=='+') temp=a+b;
if(tokens[i][0]=='-') temp=b-a;
if(tokens[i][0]=='*') temp=a*b;
if(tokens[i][0]=='/') temp=b/a;
s.push(temp);
}
}
return s.top();
}
};
Python:
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
nums = []
ops = ["+", "-", "*", "/"]
for i in range(len(tokens)):
if not tokens[i] in ops:
nums.append(int(tokens[i]))
elif tokens[i] == "+":
add1, add2 = nums[-2], nums[-1]
nums.pop()
nums.pop()
add1 = add1 + add2
nums.append(int(add1))
elif tokens[i] == "-":
sub1, sub2 = nums[-2], nums[-1]
nums.pop()
nums.pop()
sub1 = sub1 - sub2
nums.append(int(sub1))
elif tokens[i] == "*":
mul1, mul2 = nums[-2], nums[-1]
nums.pop()
nums.pop()
mul1 = mul1 * mul2
nums.append(int(mul1))
elif tokens[i] == "/":
div1, div2 = nums[-2], nums[-1]
nums.pop()
nums.pop()
div1 = div1 / div2
nums.append(int(div1))
return nums[0]