栈:1:编程语言中函数的调用
2:操作系统中从用户态到内核寄存器的保存
3:网络消息的处理。
demo1:20. 有效的括号 - 力扣(LeetCode)
cpp
class Solution
{
public:
bool isValid(string s)
{
std::map<char, char> map = {
{'(', ')'},
{'[', ']'},
{'{', '}'}};
stack<char> stack;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '(' || s[i] == '[' || s[i] == '{')
{
stack.push(s[i]);
}
else if (!stack.empty() && s[i] == map[stack.top()])
{
stack.pop();
}
else
{
return false;
}
}
return stack.empty();
}
};
python
class Solution:
def isValid(self, s):
dic = {'{': '}', '[': ']', '(': ')'} # 定义字典
stack = []
for c in s:
if c in dic:
stack.append(c)
elif len(stack) != 0 and dic[stack[-1]] == c:
stack.pop()
else:
return False
return len(stack) == 0
demo2:
cpp
int solution(vector<int> size, vector<int> dir)
{
stack<int> stack;
stack.push(dir[0]);
for (int i = 1; i < dir.size(); i++)
{
if (dir[i] == stack.top()) // 符号相同入栈
{
stack.push(dir[i]);
}
else
{
while (dir[i] == 0 && stack.top() == 1) // 符号不相同,
{
if (size[stack.top()] > size[i]) // 栈中元素大
{
break;
}
else
{ // 栈中元素小,移除,如果栈大小为0,退出
stack.pop();
if (stack.empty())
{
stack.push(dir[i]);
break;
}
}
}
}
}
return stack.size();
};
demo3
cpp
vector<int> FindRightSmall(vector<int> vec)
{
stack<int> stack; // 单调递增栈
vector<int> ret(vec.size());
stack.push(0);
for (int i = 1; i < vec.size(); i++)
{
if (vec[stack.top()] < vec[i]) // 当前元素大
{
stack.push(i);
}
else
{
while (!stack.empty() && vec[stack.top()] > vec[i]) // 当前元素小了,找到目标元素
{
ret[stack.top()] = i;
stack.pop();
}
stack.push(i);
}
}
while (!stack.empty())
{
ret[stack.top()] = -1;
stack.pop();
}
return ret;
}
python
def FindRightSmall(vec):
stack = []
ret = [-1] * len(vec)
stack.append(0)
for iter in range(1, len(vec)):
if (vec[stack[-1]] < vec[iter]):
stack.append(iter)
else:
while (len(stack) != 0 and vec[stack[-1]] > vec[iter]):
ret[stack[-1]] = iter
stack.pop()
stack.append(iter)
while (len(stack) != 0):
ret[stack[-1]] = -1
stack.pop()
return ret
demo4
vector<int> FindSmallNumber(vector<int> vec, int k)
{
stack<int> stack; // 单调递增栈
vector<int> ret(k);
stack.push(0);
for (int i = 1; i < vec.size(); i++)
{
if (vec[stack.top()] < vec[i]) // 如果右边的数大,放入
{
stack.push(i);
}
else
{
while (!stack.empty() && vec[stack.top()] > vec[i] && (stack.size() + vec.size() - i) > k) // 栈的个数加上剩余的元素大于k
{
stack.pop();
}
stack.push(i);
}
};
while (stack.size() > k)
{
stack.pop();
}
for (int i = k - 1; i >= 0; i--)
{
ret[i] = vec[stack.top()];
stack.pop();
}
return ret;
}
python
def FindSmallNumber(vec, k):
stack = []
ret = [0] * k
stack.append(0)
for iter in range(1, len(vec)):
if (vec[stack[-1]] < vec[iter]):
stack.append(iter)
else:
while (len(stack) != 0 and vec[stack[-1]] > vec[iter] and (len(stack) + len(vec)-iter > k)):
stack.pop()
stack.append(iter)
while (len(stack) > k):
stack.pop()
for iter in range(k-1, -1, -1):
ret[iter] = vec[stack[-1]]
stack.pop()
return ret
队列
demo1
cpp
// 队列遍历
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode *root)
{
if (root == nullptr)
{
return vector<vector<int>>();
}
vector<vector<int>> ret;
vector<int> ret_index;
queue<TreeNode *> que;
que.push(root);
while (!que.empty())
{
int size = que.size();
for (int i = 0; i < size; i++)
{
TreeNode *cur = que.front();
ret_index.push_back(cur->val);
que.pop();
if (cur->left != nullptr)
{
que.push(cur->left);
}
if (cur->right != nullptr)
{
que.push(cur->right);
}
}
ret.push_back(ret_index);
ret_index.clear();
}
return ret;
}
};
// 顺序遍历
// vector遍历
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode *root)
{
if (root == nullptr)
{
return vector<vector<int>>();
}
vector<vector<int>> ret;
vector<int> ret_index;
vector<TreeNode *> cur_level;
vector<TreeNode *> next_level;
if (root != nullptr)
{
cur_level.push_back(root);
}
while (!cur_level.empty())
{
for (auto iter : cur_level)
{
ret_index.push_back(iter->val);
if (iter->left != nullptr)
{
next_level.push_back(iter->left);
};
if (iter->right != nullptr)
{
next_level.push_back(iter->right);
};
}
ret.push_back(ret_index);
ret_index.clear();
cur_level = next_level;
next_level.clear();
}
return ret;
}
};
demo2
cpp
// 循环队列
// 放入元素rear+1,删除元素front+1
//[)
class MyCircularQueue
{
private:
vector<int> que;
int front = 0;
int rear = 0;
public:
MyCircularQueue(int k)
{
que.resize(k + 1);
};
bool enQueue(int value)
{
if (!isFull())
{
// 把元素放到rear位置
que[rear] = value;
// rear向后移动
rear = (rear + 1) % que.size();
return true;
}
else
{
return false;
}
};
// 出队,不删除元素
bool deQueue()
{
if (isEmpty())
{
return false;
}
else
{
front = (front + 1) % que.size();
return true;
}
};
int Front()
{
return isEmpty() ? -1 : que[front];
};
int Rear()
{
int tail = (rear + que.size() - 1) % que.size();
return isEmpty() ? -1 : que[tail];
};
bool isEmpty()
{
return rear == front;
};
bool isFull()
{
return (rear + 1) % que.size() == front;
};
};
demo3
cpp
// 非严格单调递减双端队列
class Solution
{
private:
deque<int> que;
vector<int> vec;
private:
void DecreasingQueue(int index)
{
while (!que.empty() && vec[que.back()] <= vec[index])
{
que.pop_back();
}
que.push_back(index);
}
public:
vector<int> maxSlidingWindow(vector<int> &nums, int k)
{
vector<int> ret;
// 单调递减队列
vec = nums;
for (int i = 0; i < k; i++)
{
DecreasingQueue(i);
}
ret.push_back(nums[que.front()]);
for (int i = k; i < nums.size(); i++)
{
DecreasingQueue(i);
// 第一个元素超过限制
if (i - que.front() >= k)
{
que.pop_front();
}
ret.push_back(nums[que.front()]);
};
return ret;
}
};