1. 窗口
例1:
/**
*@ w:窗口大小
*@ return:每个窗口中最大值组成的数组
*/
int *getMaxWindow(int *arr, int len, int w)
{
deque<int> dqMax; //dqMax存放数组下标
int *ret = new int[len - w + 1];
int index = 0;
for (int i = 0; i < len; i++)
{
while (!dqMax.empty() && arr[dqMax.back()] <= arr[i]) //保证队中元素从大到小
dqMax.pop_back();
dqMax.push_back(i);
if (i - w == dqMax.front()) //窗口大小 > w, 队头出队
dqMax.pop_front();
ret[index++] = arr[dqMax.front()];
}
return ret;
}
例2:
int getNum(int *arr, int len, int num)
{
deque<int> dqMax; //存放数组下标
deque<int> dqMin; //存放数组下标
int L = 0;
int R = 0;
int ret = 0;
while (L < len) //arr[L,R] 以 L 为开头,符合要求的子数组数量为 R-L
{
while (R < len)
{
while (!dqMin.empty() && arr[dqMin.back()] >= arr[R])
dqMin.pop_back();
dqMin.push_back(R);
while (!dqMax.empty() && arr[dqMax.back() <= arr[R])
dqMax.pop_back();
dqMax.push_back(R);
if (arr[dqMax.front()] - arr[dqMax.front()] > num)
break;
R++;
}
if (dqMin.front() == L)
dqMin.pop_front();
if (dqMax.front() == L)
dqMax.pop_front();
ret += R - L;
L++;
}
return ret;
}
2. 单调栈
求一个数组中每个数左边比它大的最近数和右边比它大的最近数(反之亦然)
相等情况
进阶7~3
7min到14min项目技巧
引子
数组[4,3,2,5,6]代表直方图的高度,找出直方图中矩形面积最大值
int maxRecArea(int *height, int len)
{
if (!height || len == 0)
return 0;
int maxArea = 0;
stack<int> sta;
for (int i = 0; i < len; i++)
{
while (!sta.empty() && height[sta.top()] >= height[i])
{
int h = height[sta.top()];
sta.pop();
int l = sta.empty() ? -1 : sta.top(); //左边界
int area = (i - l - 1)*h;
maxArea = max(maxArea, area);
}
sta.push(i);
}
while (!sta.empty())
{
int h = height[sta.top()];
sta.pop();
int l = sta.empty() ? -1 : sta.top(); //左边界
int area = (len - l - 1)*h;
maxArea = max(maxArea, area);
}
return maxArea;
}
思路:
int maxRecSize(int** map, int m, int n)
{
if (!map) return 0;
int maxArea = 0;
int *array = new int[n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
array[j] = (map[i][j] == 0) ? 0 : array[j] + 1;
maxArea = max(maxArea, maxRecArea(array, n));
}
return maxArea;
}
烽火相望
参考链接