力扣算法秘籍:用STL容器适配器破解经典栈/队列问题
·
力扣算法秘籍:STL容器适配器破解栈/队列问题
栈和队列是算法中的基础数据结构,STL提供的容器适配器能高效解决相关问题。以下是经典问题的解法秘籍:
一、栈适配器(stack)应用
问题:有效的括号(LeetCode 20)
验证括号字符串是否合法,如 "()[]{}" 有效,"(]" 无效。
bool isValid(string s) {
stack<char> st;
for (char c : s) {
if (c == '(' || c == '[' || c == '{') st.push(c);
else {
if (st.empty()) return false;
char top = st.top();
if ((c == ')' && top != '(') ||
(c == ']' && top != '[') ||
(c == '}' && top != '{')) return false;
st.pop();
}
}
return st.empty();
}
核心思想:
遇到左括号入栈,右括号时检查栈顶是否匹配。时间复杂度:$O(n)$,空间复杂度:$O(n)$。
二、队列适配器(queue)应用
问题:用栈实现队列(LeetCode 232)
仅用栈操作实现队列的 push、pop、peek、empty。
class MyQueue {
private:
stack<int> in, out;
void transfer() {
while (!in.empty()) {
out.push(in.top());
in.pop();
}
}
public:
void push(int x) { in.push(x); }
int pop() {
if (out.empty()) transfer();
int val = out.top();
out.pop();
return val;
}
int peek() {
if (out.empty()) transfer();
return out.top();
}
bool empty() { return in.empty() && out.empty(); }
};
设计要点:
in栈处理入队,out栈处理出队- 当
out为空时,将in中元素全部转移 - 均摊时间复杂度:$O(1)$
三、优先级队列(priority_queue)应用
问题:数组中的第K大元素(LeetCode 215)
在未排序数组中找到第K大的元素,如 [3,2,1,5,6,4] 的K=2时返回5。
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> pq; // 最小堆
for (int num : nums) {
pq.push(num);
if (pq.size() > k) pq.pop();
}
return pq.top();
}
优化策略:
- 维护大小为K的最小堆
- 堆顶即为第K大元素
- 时间复杂度:$O(n \log k)$
四、综合应用:滑动窗口最大值(LeetCode 239)
问题:给定数组和窗口大小k,返回每个窗口的最大值序列。
如 nums = [1,3,-1,-3,5,3,6,7], k = 3 时输出 [3,3,5,5,6,7]。
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> dq; // 双端队列存储索引
vector<int> res;
for (int i = 0; i < nums.size(); ++i) {
// 移除超出窗口的元素
if (!dq.empty() && dq.front() == i - k) dq.pop_front();
// 维护单调递减队列
while (!dq.empty() && nums[dq.back()] < nums[i])
dq.pop_back();
dq.push_back(i);
if (i >= k - 1) res.push_back(nums[dq.front()]);
}
return res;
}
关键技巧:
- 使用双端队列维护索引而非值
- 队列保持单调递减(队头始终为最大值)
- 时间复杂度:$O(n)$,空间复杂度:$O(k)$
总结:STL适配器的核心优势
stack:后进先出(LIFO),适合对称性问题queue:先进先出(FIFO),适合顺序处理priority_queue:自动排序,适合TopK问题
掌握这些工具能高效解决90%的栈/队列相关问题!
更多推荐
所有评论(0)