删除字符串中的相邻重复项
利用栈的思想来实现,解题链接
class Solution {
public:
string removeDuplicates(string S) {
string stack;
for(char ch : S)
{
if(!stack.empty() && stack.back() == ch)
{
stack.pop_back();
}
else
{
stack.push_back(ch);
}
}
return stack;
}
};
有效括号
官方解法
利用 栈+哈希表 配合完成
class Solution {
public:
bool isValid(string s) {
if (s.size() % 2)
return false;
unordered_map<char,char> m{
{')','('},
{']','['},
{'}','{'}
};
stack <char> st;
for(char ch : s)
{
if(m.count(ch))
{
if(st.empty() || st.top() != m[ch] )
{
return false;
}
st.pop();
}
else
{
st.push(ch);
}
}
return st.empty();
}
};
最小栈
官方解法
这思路都不是人想的,完全没想到这么做,不是解题思路不会,是不懂题意,怀疑N+1天
class MinStack {
public:
/** initialize your data structure here. */
stack <int> x_stack;
stack <int> min_stack;
MinStack() {
min_stack.push(INT_MAX);
}
void push(int val) {
x_stack.push(val);
//永远保留最小值
min_stack.push(min(min_stack.top(),val));
}
void pop() {
//x_stack 和 Min_stack 保持同步
x_stack.pop();
min_stack.pop();
}
int top() {
return x_stack.top();
}
int getMin() {
return min_stack.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
用队列实现栈
用两个队列实现栈
class MyStack {
public:
queue<int> q1;
queue<int> q2;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
//1、自己写的,两次遍历,复杂度偏高了
// while(!q1.empty())
// {
// q2.push(q1.front());
// q1.pop();
// }
// q1.push(x);
// while(!q2.empty())
// {
// q1.push(q2.front());
// q2.pop();
// }
//2、官方解法,一次遍历,交换容器
q2.push(x);
while(!q1.empty())
{
q2.push(q1.front());
q1.pop();
}
swap(q1,q2);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int r = q1.front();
q1.pop();
return r;
}
/** Get the top element. */
int top() {
return q1.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q1.empty();
}
};
时间复杂度:入栈操作 O(n),其余操作都是 O(1)。
入栈操作需要将queu1中的 n 个元素出队,并入队 n+1个元素到queue2,共有2n+1 次操作,每次出队和入队操作的时间复杂度都是 O(1),因此入栈操作的时间复杂度是 O(n)。
出栈操作对应将queue 的前端元素出队,时间复杂度是 O(1)O(1)。
获得栈顶元素操作对应获得 queue1的前端元素,时间复杂度是 O(1)O(1)。
判断栈是否为空操作只需要判断queue 1是否为空,时间复杂度是 O(1)O(1)。
空间复杂度:O(n),其中 n 是栈内的元素。需要使用两个队列存储栈内的元素。
用一个队列实现栈
class MyStack {
public:
queue<int> q;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
//关键在于将队列中的已有数据重新取出,移动至队尾
int n = q.size();
q.push(x);
for (int i = 0; i < n; i++) {
q.push(q.front());
q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int r = q.front();
q.pop();
return r;
}
/** Get the top element. */
int top() {
int r = q.front();
return r;
}
/** Returns whether the stack is empty. */
bool empty() {
return q.empty();
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/implement-stack-using-queues/solution/yong-dui-lie-shi-xian-zhan-by-leetcode-solution/
用栈实现队列
个人解法
两次遍历
class MyQueue {
public:
stack <int> s1,s2;
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
//两次遍历 ,实现 两个 栈之间的数据转移
void push(int x) {
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
s1.push(x);
while(!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int r = s1.top();
s1.pop();
return r;
}
/** Get the front element. */
int peek() {
return s1.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return s1.empty();
}
};
官方解法
class MyQueue {
private:
stack<int> inStack, outStack;
void in2out() {
while (!inStack.empty()) {
outStack.push(inStack.top());
inStack.pop();
}
}
public:
MyQueue() {}
void push(int x) {
inStack.push(x);
}
int pop() {
if (outStack.empty()) {
in2out();
}
int x = outStack.top();
outStack.pop();
return x;
}
int peek() {
if (outStack.empty()) {
in2out();
}
return outStack.top();
}
bool empty() {
return inStack.empty() && outStack.empty();
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/yong-zhan-shi-xian-dui-lie-by-leetcode-s-xnb6/
时间复杂度:push 和 empty 为 O ( 1 ) O(1) O(1),pop 和peek 为均摊O(1),空间复杂度为 O ( n ) O(n) O(n)。
去除重复字母
class Solution {
public:
string removeDuplicateLetters(string s) {
//num用来记录字符串s 中各个字符的个数
//vis 用于判断新建的栈中是否已有当前字母,如果有不再入栈,如果没有,入栈,判断当前字符
//是否小于栈顶字符,若小且原字符串s中依旧有栈顶字符,则将栈顶字符出栈,并清楚标志位,直到
//当前字符大于栈顶字符
//num记录26个字母 在字符串s中的个数,分别记录在对应位置中
//vis 统计栈中字符个数
vector <int> vis(26),num(26);
// num 统计原字符串中 各个字符的个数
for(char ch : s)
{
num[ch - 'a'] ++;
}
string stk;
for(char ch : s)
{
//如果栈中当前字符数为0,压栈,vis自加
//栈中全部字符不可重复
if(!vis[ch - 'a'])
{
//比较当前字符与栈中字符优先级,优先级小且原字符串中仍有栈顶字符,则出栈
while(!stk.empty() && stk.back() > ch)
{
//原字符串中仍有栈顶字符
if(num[stk.back() - 'a'] > 0)
{
vis[stk.back() - 'a'] = 0;
stk.pop_back();
}
else
{
break;
}
}
vis[ch - 'a'] =1;
stk.push_back(ch);
}
//原字符串字符数自减
num[ch - 'a'] -= 1;
}
return stk;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/remove-duplicate-letters/solution/qu-chu-zhong-fu-zi-mu-by-leetcode-soluti-vuso/