【leetcode题解C++】150.逆波兰表达式求值 and 239.滑动窗口最大值 and 347.前k个高频元素

150.逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+''-''*' 和 '/' 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

思路: 注意到,后序表达式,那么用栈,遇到数字就压入栈,遇到运算符就取两个数字出来运算,得到ans压入栈,继续循环直到没有元素可以读取。需要注意的是,如果过只给一个数字,那么需要用top()来获取。

代码实现:

class Solution {
public:
    int evalRPN(vector& tokens) {
        int ans = 0;
        stack stk;
        int num1 = 0, num2 = 0;
        for(int i = 0; i < tokens.size(); ++i) {
            if(tokens[i] == "+" || tokens[i] == "-" 
              || tokens[i] == "*" || tokens[i] == "/") {
                num1 = stk.top();stk.pop();
                num2 = stk.top();stk.pop();
                if(tokens[i] == "+") ans = num2 + num1;
                if(tokens[i] == "-") ans = num2 - num1;
                if(tokens[i] == "*") ans = num2 * num1;
                if(tokens[i] == "/") ans = num2 / num1;
                stk.push(ans);
            }
            else {
                stk.push(stoi(tokens[i]));
            }
        }
        ans = stk.top();
        return ans;
    }
};

239.滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

示例 1:

输入: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

示例 2:

输入:nums = [1], k = 1
输出:[1]

思路:读题后发现很暴力很直接,很顺畅就用一个queue和一个vector写出了暴力的解法,感叹困难题不过尔尔,提交发现超时...真是事与愿违,后面学到了单调队列,用一个队列,维护队首的元素永远是最大的(下面维护的是下标),首先处理最前面k个元素,然后初始化需要返回的vector,然后再处理后面的元素,直到读取到最后一个元素。

代码实现:

class Solution {
public:
    vector maxSlidingWindow(vector& nums, int k) {
        deque deq;
        for(int i = 0; i < k; ++i) {
            while(!deq.empty() && nums[i] >= nums[deq.back()]) {
                deq.pop_back();
            }
            deq.push_back(i);
        }
        vector ans = {nums[deq.front()]};
        for(int i = k; i < nums.size(); ++i) {
            while(!deq.empty() && nums[i] >= nums[deq.back()]) {
                deq.pop_back();
            }
            deq.push_back(i);
            while(deq.front() <= i - k) {
                deq.pop_front();
            }
            ans.push_back(nums[deq.front()]);
        }
        return ans;
    }
};

347.前k个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:

输入: nums = [1], k = 1
输出: [1]

思路:?直~~接返回二维数组,先用个哈希map来记录每个元素的出现次数,然后加入到二维数组中,sort()一下,需要个排序的条件?甩个lambda表达式,ok排完序了,建一个vector来把前k个结果接出去。

代码实现:

class Solution {
public:
    vector topKFrequent(vector& nums, int k) {
        unordered_map map;
        for(int i = 0; i < nums.size(); ++i) {
            ++map[nums[i]];
        }
        vector> vec;
        for(auto& [x, y] : map) {
            vec.push_back({x, y});
        }
        sort(vec.begin(), vec.end(), 
            [](const vector& a, const vector& b) {return a[1] > b[1];}
            );
        vector res;
        for(int i = 0; i < k && i < vec.size(); ++i) {
            res.push_back(vec[i][0]);
        }
        return res;
    }
};

你可能感兴趣的:(leetcode,leetcode,c++,算法)