单调栈 发表于 2019-09-27 | 分类于 leetcode | 浏览 次 什么是单调栈? 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126#include <iostream>#include <vector>#include <stack>using namespace std;/** * 对于不含重复元素的数组求其中每个元素左边和右边小于该元素且距离该元素最近的位置 */vector<vector<int>> getNearLessNoRepeat(vector<int> &arr) { vector<vector<int>> res(arr.size(), vector<int>(2, -1)); stack<int> s1; for (int i = 0; i < arr.size(); ++i) { while (!s1.empty() && arr[s1.top()] > arr[i]) { int popIndex = s1.top(); s1.pop(); int left = s1.empty() ? -1 : s1.top(); res[popIndex][0] = left; res[popIndex][1] = i; } s1.push(i); } while (!s1.empty()) { int popIndex = s1.top(); s1.pop(); int left = s1.empty() ? -1 : s1.top(); res[popIndex][0] = left; res[popIndex][1] = -1; } return res;}/** * 对于含重复元素的数组求其中每个元素左边和右边小于该元素且距离该元素最近的位置 * 方法1:把所有相等元素放到一个vector中 */vector<vector<int>> getNearLess(vector<int> &arr) { vector<vector<int>> res(arr.size(), vector<int>(2, -1)); stack<vector<int>> s1; for (int i = 0; i < arr.size(); ++i) { while (!s1.empty() && arr[s1.top()[0]] > arr[i]) { vector<int> popIs = s1.top(); s1.pop(); int left = s1.empty() ? -1 : s1.top()[s1.top().size() - 1]; for (int popi : popIs) { res[popi][0] = left; res[popi][1] = i; } } if (!s1.empty() && arr[s1.top()[s1.top().size() - 1]] == arr[i]) { s1.top().push_back(i); } else { vector<int> tmp{i}; s1.push(tmp); } } while (!s1.empty()) { vector<int> popIs = s1.top(); s1.pop(); int left = s1.empty() ? -1 : s1.top()[s1.top().size() - 1]; for (int popi: popIs) { res[popi][0] = left; res[popi][1] = -1; } } return res;}/** * 对于含重复元素的数组求其中每个元素左边和右边小于该元素且距离该元素最近的位置 * 方法2:对于每个元素从栈中退出时才统计与其相等的元素 */vector<vector<int>> getNearLess2(vector<int> &arr) { vector<vector<int>> res(arr.size(), vector<int>(2, -1)); stack<int> s1; for (int i = 0; i < arr.size(); ++i) { int right = i; while (!s1.empty() && arr[s1.top()] > arr[i]) { int idx = s1.top(); vector<int> tmp{idx}; while (!s1.empty() && arr[s1.top()] == arr[idx]) { tmp.push_back(s1.top()); s1.pop(); } int left = s1.empty() ? -1 : s1.top(); for (auto index : tmp) { res[index][0] = left; res[index][1] = right; } } s1.push(i); } int right = -1; while (!s1.empty()) { int idx = s1.top(); vector<int> tmp{idx}; while (!s1.empty() && arr[idx] == arr[s1.top()]) { tmp.push_back(s1.top()); s1.pop(); } int left = s1.empty() ? -1 : s1.top(); for (auto index:tmp) { res[index][0] = left; res[index][1] = right; } } return res;}int main() { vector<int> arr{3, 1, 3, 4, 3, 5, 3, 2, 2}; vector<vector<int>> res1 = getNearLess(arr); vector<vector<int>> res2 = getNearLess2(arr); for (int i = 0; i < arr.size(); ++i) { cout << arr[i] << " " << res1[i][0] << " " << res1[i][1] << endl; } cout << endl; for (int i = 0; i < arr.size(); ++i) { cout << arr[i] << " " << res2[i][0] << " " << res2[i][1] << endl; } cout << endl; return 0;} 单调栈的应用 Maximal Square