鱼C论坛

 找回密码
 立即注册
查看: 2557|回复: 4

[技术交流] C++刷剑指offer(面试题59 - I. 滑动窗口的最大值)【滑动窗口】

[复制链接]
发表于 2020-3-26 11:49:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 糖逗 于 2020-5-8 17:21 编辑

题目出处:leetcode
面试题59 - I. 滑动窗口的最大值
题目描述:
  1. 给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

  2. 示例:

  3. 输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
  4. 输出: [3,3,5,5,6,7]
  5. 解释:

  6.   滑动窗口的位置                最大值
  7. ---------------               -----
  8. [1  3  -1] -3  5  3  6  7       3
  9. 1 [3  -1  -3] 5  3  6  7       3
  10. 1  3 [-1  -3  5] 3  6  7       5
  11. 1  3  -1 [-3  5  3] 6  7       5
  12. 1  3  -1  -3 [5  3  6] 7       6
  13. 1  3  -1  -3  5 [3  6  7]      7
复制代码


  1. #include <iostream>
  2. #include <vector>
  3. #include <deque>
  4. using namespace std;

  5. vector<int> solution(vector<int>& input, int k){
  6.         vector<int> result;
  7.         deque<int> temp;
  8.         int front_arrow = 0;
  9.         if(input.size() == 0 || k == 1) return input;
  10.         for(int i = 0; i < input.size(); i++){
  11.                 if(temp.empty()){
  12.                         temp.push_back(i);
  13.                         continue;
  14.                 };
  15.                 if(input[i] >= input[temp.front()]){
  16.                         temp.clear();
  17.                         temp.push_front(i);
  18.                 }
  19.                 else{
  20.                         while(input[i] >= input[temp.back()]){
  21.                                 temp.pop_back();
  22.                         }
  23.                         temp.push_back(i);       
  24.                 }
  25.                
  26.                 while(temp.front() <= i - k){
  27.                         temp.pop_front();
  28.                 }
  29.                 if(i >= k - 1){
  30.                         result.push_back(input[temp.front()]);
  31.                 }
  32.         }
  33.         return result;
  34. }



  35. int main(void){
  36.         int num;
  37.     cout << "send vector" << endl;
  38.     vector<int> list;
  39.     while(cin >> num)
  40.     {
  41.         list.push_back(num);
  42.     }
  43.     cout << endl;
  44.     cout << "send k" <<endl;
  45.     cin.clear();
  46.         int k;
  47.         cin >> k;
  48.         vector<int> result;
  49.         result = solution(list, k);
  50.         for(int i = 0; i < result.size(); i++){
  51.                 cout << result[i];
  52.         }
  53.         cout << endl;
  54.         return 0;
  55. }
复制代码



参考链接:
https://www.bilibili.com/video/B ... 1078736512342441171
https://blog.csdn.net/Chnyac/article/details/82710050


注意事项:
1.检查当前最大值是否在滑动窗口内。
2.deque双向队列中存储的是当前值的下标序号。


相同思路的题:面试题59 - II. 队列的最大值
  1. 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

  2. 若队列为空,pop_front 和 max_value&#160;需要返回 -1

  3. 示例 1:

  4. 输入:
  5. ["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
  6. [[],[1],[2],[],[],[]]
  7. 输出:&#160;[null,null,null,2,1,2]
  8. 示例 2:

  9. 输入:
  10. ["MaxQueue","pop_front","max_value"]
  11. [[],[],[]]
  12. 输出:&#160;[null,-1,-1]
  13. &#160;

  14. 限制:

  15. 1 <= push_back,pop_front,max_value的总操作数&#160;<= 10000
  16. 1 <= value <= 10^5

复制代码
  1. class MaxQueue {
  2. public:
  3.     queue<int> input;
  4.     deque<int> temp;
  5.     MaxQueue() {

  6.     }
  7.    
  8.     int max_value() {
  9.         if(temp.empty()) return -1;
  10.         else{
  11.             return temp.front();
  12.         }

  13.     }
  14.    
  15.     void push_back(int value) {
  16.         input.push(value);
  17.         if(temp.empty()) temp.push_back(value);
  18.         else{
  19.             if(value >= temp.front()){
  20.                 temp.clear();
  21.                 temp.push_front(value);
  22.             }
  23.             else{
  24.                 while(value >= temp.back()){
  25.                     temp.pop_back();
  26.                 }
  27.                 temp.push_back(value);
  28.             }
  29.         }
  30.     }

  31.     int pop_front() {
  32.         if(input.empty()) return -1;
  33.         int result;
  34.         result = input.front();
  35.         input.pop();
  36.         if(result == temp.front()){
  37.             temp.pop_front();
  38.         }

  39.         return result;
  40.     }
  41. };

  42. /**
  43. * Your MaxQueue object will be instantiated and called as such:
  44. * MaxQueue* obj = new MaxQueue();
  45. * int param_1 = obj->max_value();
  46. * obj->push_back(value);
  47. * int param_3 = obj->pop_front();
  48. */
复制代码



相同思路的题:面试题63. 股票的最大利润
题目描述:
  1. 假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

  2. &#160;

  3. 示例 1:

  4. 输入: [7,1,5,3,6,4]
  5. 输出: 5
  6. 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
  7.      注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
  8. 示例 2:

  9. 输入: [7,6,4,3,1]
  10. 输出: 0
  11. 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
复制代码

  1. #include<iostream>
  2. #include<deque>
  3. #include<vector>
  4. using namespace std;

  5. int solution(vector<int>& input){
  6.         deque<int> temp;
  7.         if(input.size() == 0) return 0;
  8.         int compare = 0;
  9.         for(int i = 0; i < input.size(); i++){
  10.                 if(temp.empty()) temp.push_back(input[i]);
  11.                 else{
  12.                         if(input[i] < temp.back()){
  13.                                 compare = (temp.front() - temp.back()) > compare ? temp.front() - temp.back() : compare;
  14.                                 temp.clear();
  15.                                 temp.push_back(input[i]);
  16.                         }
  17.                         if(input[i] > temp.front()){
  18.                                 temp.push_front(input[i]);
  19.                         }
  20.                 }
  21.                        
  22.         }
  23.         compare = (temp.front() - temp.back()) > compare ? temp.front() - temp.back() : compare;
  24.         return compare;

  25. }



  26. int main(void){
  27.         int number;
  28.         vector<int> input;
  29.         int result;
  30.         while(cin >> number){
  31.                 input.push_back(number);
  32.         }
  33.        
  34.         result = solution(input);
  35.         cout << result << endl;
  36.         return 0;
  37. }
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-24 16:54:34 From FishC Mobile | 显示全部楼层
这道出题高频
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-24 19:16:53 | 显示全部楼层
剑指 Offer 59 - I. 滑动窗口的最大值(双指针)
  1. class Solution {
  2. public:
  3.     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
  4.         int left = 0, right = 0;
  5.         vector<int> res;
  6.         int len = nums.size();
  7.         if(len == 0)return res;
  8.         while(left < len - k + 1){
  9.             int temp = nums[left];
  10.             while(right < len && right - left + 1 <= k){
  11.                 temp = max(temp, nums[right]);
  12.                 right++;
  13.             }
  14.             left++;
  15.             res.push_back(temp);
  16.             right = left;
  17.         }
  18.         return res;
  19.     }
  20. };
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-15 14:14:38 | 显示全部楼层
可以 这道题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-15 22:16:59 | 显示全部楼层

谢谢回评!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-3 08:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表