实际开发中,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题。
class MyQueue {
public:
stack<int>stIn;// 输入栈
stack<int>stOut;// 输出栈
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
int ret = stOut.top();
stOut.pop();
return ret;
}
int peek() {
int ret = pop();// 直接调用pop,然后在把对应元素push回去
stOut.push(ret);
return ret;
}
bool empty() {
return stIn.empty() && stOut.empty();
}
};
class MyStack {
public:
queue<int>que1;
queue<int>que2;// 起辅助作用
MyStack() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size();
size--;
while(size--){
que2.push(que1.front());
que1.pop();
}
int ret = que1.front();
que1.pop();
que1 = que2;// que2作用
// 清空que2
while(!que2.empty()){
que2.pop();
}
return ret;
}
int top() {
return que1.back();
}
bool empty() {
return que1.empty();
}
};
class MyStack {
public:
queue<int>que1;
MyStack() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size();
size--;
while(size--){
que1.push(que1.front());
que1.pop();
}
int ret = que1.front();
que1.pop();
return ret;
}
int top() {
return que1.back();
}
bool empty() {
return que1.empty();
}
};
class Solution {
public:
bool isValid(string s) {
stack<char>st;
for(char& c:s){
// if(st.empty())st.push(c);
if(c == ')'){
if(!st.empty() && st.top() == '(')st.pop();// 是否可以匹配
else{
return false;// 无法匹配
//st.push(c);
}
}else if(c == ']'){
if(!st.empty() && st.top() == '[')st.pop();
else{
return false;
//st.push(c);
}
}else if(c == '}'){
if(!st.empty() && st.top() == '{')st.pop();
else{
return false;
//st.push(c);
}
}else{
st.push(c);
}
}
return st.empty();
}
};
class Solution {
public:
bool isValid(string s) {
// 奇数长度,肯定不符合
if(s.size() % 2 != 0)return false;
stack<int>st;
for(char& c:s){
if(c == '(')st.push(')');
else if(c == '[')st.push(']');
else if(c == '{')st.push('}');
else if(st.empty() || c != st.top())return false;// 如果为空,则说明还没有左括号呢,此时这个c为右括号,无法匹配成功。
else st.pop();// c == st.top(),到这里肯定是非空
}
return st.empty();
}
};
class Solution {
public:
string removeDuplicates(string s) {
stack<char>st;
for(char& c:s){
if(!st.empty() && st.top() == c)st.pop();// 注意条件控制,栈要非空。
else st.push(c);
}
string ret;
while(!st.empty()){
ret += st.top();
st.pop();
}
reverse(ret.begin(),ret.end());
return ret;
}
};
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long>st;
int ret = 0;
for(string &s:tokens){
// 如果是符号,则取出两个数,然后进行运算->push回去
if(s == "+" || s == "-" || s == "*" || s == "/"){
long long num1 = st.top();
st.pop();
long long num2 = st.top();
st.pop();
// 注意运算符是谁对谁后一个对前一个
if(s == "+")st.push(num2+num1);
else if(s == "-")st.push(num2-num1);
else if(s == "*")st.push(num2*num1);
else if(s == "/")st.push(num2/num1);
}else st.push(stoll(s));
}
return st.top();// 栈中剩的最后一个值为最终结果
}
};
class Solution {
public:
class myQueue{
deque<int>que;
public:
void pop(int v){ // 如果当前要pop的元素是队头的,即最大的,那就pop,否则继续保留最大的。
if(!que.empty() && v == que.front()){
que.pop_front();
}
}
// 从后面开始,如果要放入窗口的元素大于后面的。
// 那就pop出来,最终将v push进去,要么为最大的,要么队列中v前面有最大的。
// 使得,队头的元素肯定为当前窗口的最大值。
void push(int v){
while(!que.empty() && v > que.back()){
que.pop_back();
}
que.push_back(v);
}
// 取得队头元素,即当前窗口的最大值。
int front(){
return que.front();
}
};
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int>ret;
myQueue que;
// 先往里面弄k个,这样下面才能统一管理
for(int i = 0; i < k ;i++){
que.push(nums[i]);
}
ret.push_back(que.front());
for(int i = k ;i < nums.size();i++){
// 下面两步为窗口的移动,这两步的先后顺序无影响。
que.pop(nums[i-k]);// 去掉最左边元素
que.push(nums[i]);// 去掉最右边元素
// 收集结果
ret.push_back(que.front());
}
return ret;
}
};
class Solution {
public:
// 小顶堆排序
class myComparion{
public:
// k v:元素-频率,按照频率排序,堆顶为频率小的——小顶堆。
bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
// 统计元素出现的频率
unordered_map<int,int>map;// map[nums[i]]对应元素出现的次数
for(int i = 0; i < nums.size();i++){
map[nums[i]]++;
}
// 小顶堆
// k-v 元素-频率
priority_queue<pair<int,int>,vector<pair<int,int>>,myComparion>pri_que;
// 用固定大小为k的小顶堆,扫描所有频率的数值
for(unordered_map<int,int>::iterator it = map.begin();it != map.end();it++){
pri_que.push(*it);
if(pri_que.size() > k){// 如果堆中的元素数量大于k,则弹出堆顶元素,即
pri_que.pop();
}
}
// 找出前k个高频元素,因为小顶推先弹出的是最小的,所以倒叙来输出到数组中
// 我们要的是从频率高的到频率低的。
vector<int>ret(k);
for(int i = k-1;i >=0 ;i--){// 实际上队列中最多也就维持了k个元素,如上面循环中所示。
ret[i] = pri_que.top().first;
pri_que.pop();
}
return ret;
}
};