《剑指offer》面试题65:滑动窗口的最大值

题目:

    给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组{2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小为3,那么一共存在6个滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6 , 5}。

思路:

    解法一:碰到这种题目首先想到的是,每次扫描每一个滑动窗口的所有数字并找出最大值。如果滑动窗口为 k,数组的元素有 n 个,那么时间复杂度为(kn)。   

    解法二:使用队列数据结构来保存滑动窗口的元素的下标,队列头部保存的是滑动窗口的最大值,每移动一个元素,则比较当前元素和队尾元素的大小,如果队尾元素比当前元素大,则移除队尾的元素,直到队列为空或者队列内的元素比当前元素大。具体的代码如下:

//
// Created by 陈国威 on 2018/6/15.
//

/*
 *  题目:滑动窗口的最大值
 * */
#include <iostream>
#include <vector>
#include <deque>

using namespace std;

vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
  vector<int> maxInWindows;
  if (num.size() >= size && size >= 1)
    {
      deque<int> index;

      // 刚开始输入 size 个元素
	  for (unsigned int i = 0; i < size; i++)
		{
		  while (!index.empty () && num[i] >= num[index.back ()])
			index.pop_back ();

		  index.push_back (i);
		}

	  for (unsigned int i = size; i < num.size (); i++)
		{
		  maxInWindows.push_back (num[index.front ()]);

		  while (!index.empty () && num[i] > num[index.back ()]) // 如果移动的当前元素比队列中的大,则移除队列中的元素
			index.pop_back ();

		  if (!index.empty () && index.front () <= (int)(i - size)) // 如果当前队列头的元素滑出了窗口,则移除
			index.pop_front ();

		  index.push_back (i);
		}

	  maxInWindows.push_back (num[index.front ()]);
    }

  return maxInWindows;
}


 
 

参照:

    《剑指offer》

猜你喜欢

转载自blog.csdn.net/gochenguowei/article/details/80789626