今天刷的内容全都是leetcode中栈和队列的使用
leetcode20:判断是否是匹配括号等;
class Solution {
public:
bool isValid(string s) {
int size=s.length();
if(size%2!=0){
return false;
}
stack<char> Stack;//构建一个stack
int i;
for(i=0;i<size;i++){
if(s[i]=='('||s[i]=='{'||s[i]=='['){
Stack.push(s[i]);
}
else{
if(Stack.empty())
return false;
if((Stack.top()=='('&&s[i]==')')||(Stack.top()=='{'&&s[i]=='}')||(Stack.top()=='['&&s[i]==']'))
Stack.pop();
}
}
if(Stack.empty()){
return true;
}
else
return false;
}
};
构建一个栈数据结构来存储相应的数据,如果是左括号就入栈,如果是右括号就出栈,直到所有元素都遍历,如果栈不为空则返回false;
leetcode150:波特兰后续表达式计算,学习的内容是atoi()函数的使用;,时间复杂度都是O(n);
class Solution {
public:
int evalRPN(vector<string>& tokens) {
int size=tokens.size();
if(size==1){
return atoi(tokens[0].c_str());
}
stack<int> ss;
int i=0;
for(i;i<size;i++){
if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){
//首先将字符串转换为C字符串,然后转换为int类型的数据
ss.push(atoi(tokens[i].c_str()));
}
else{
int m=ss.top();
ss.pop();
int n=ss.top();
ss.pop();
if(tokens[i]=="+") ss.push(m+n);
if(tokens[i]=="-") ss.push(n-m);
if(tokens[i]=="*") ss.push(m*n);
if(tokens[i]=="/") ss.push(n/m);
}
}
return ss.top();
};
leetcode71:简化一个字符串linux文件路径的字符串:
class Solution {
public:
string simplifyPath(string path) {
//简化路径名称 使用一个栈来维护字符串
int size=path.size();
int i=0;
if(path=="") return "";
stack<string> stacks;
//首先遍历所有的字符串中的字符
for(i=0;i<size;){
while(i<size&&path[i]=='/'){
i++;
}
string s="";
while(i<size&&path[i]!='/'){
s+=path[i++];
}
if(s==".."&&!stacks.empty()){
stacks.pop();// 如果是..弹出相应的元素
}
else{
if(s!=".."&&s!="."&&s!=""){
stacks.push(s);
}
}
}
if(stacks.empty()){
return "/";//如果当前的栈为空 返回当前路径
}
string ans="";
while(!stacks.empty())
{
ans="/"+stacks.top()+ans;
stacks.pop();
}
return ans;
}
};
算法的和时间复杂度为O(n);
栈和递归的紧密联系:与二叉树的使用;
leetcode144; 先序遍历算法的使用
1:递归算法的简单实现:
class Solution {
public:
vector<int> ans;//增加一个类变量来维护相应的数据
public:
if(root){
ans.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
return ans;
}
};
居然能通过 运算时间是4ms
2.自己模拟一个栈了维护相应的数据;
struct command{
string flag;
TreeNode* node;
command(string ss,TreeNode *Node):flag(ss),node(Node){}
};//主机构建一个结构体来存储相应的Node节点还有一个flag标志
class Solution {
public:
vector<int> ans;
public:
vector<int> preorderTraversal(TreeNode* root) {
//使用栈来模拟递归算法的使用;
if(root==NULL){
return ans;
}
stack<command> result;
result.push(command("go",root));//首先将根节点入栈中
while(!result.empty()){
command top=result.top();
result.pop();
if(top.flag=="out"){
ans.push_back((top.node)->val);
}
else{//对于每一次节点都要进行相应的入栈
if(top.node->right!=NULL){
result.push(command("go",top.node->right));
}
if(top.node->left!=NULL){
result.push(command("go",top.node->left));
}
result.push(command("out",top.node));
}
}
return ans;
}
};
以上的运行时间为3ms
3:采用书本中的构建栈的方式较为复杂:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
TreeNode *p=root;
if(root==NULL){
return ans;
}
stack<TreeNode *> ss;
while(p!=NULL||!ss.empty()){
while(p!=NULL){
ans.push_back(p->val);
ss.push(p);
p=p->left;
}//首先遍历左行节点到最根部,然后再push进右节点;
if(!ss.empty()){
TreeNode *q=ss.top();
ss.pop();
p=q->right;
}
}
return ans;
}
同理相应的中序遍历的方式也是一样的:
leetcode94:
递归实现:
class Solution {//中序遍历算法
public:
vector<int> ans;//同样设置一个类属性来存储相应的返回值
vector<int> inorderTraversal(TreeNode* root) {
if(root){
inorderTraversal(root->left);
ans.push_back(root->val);
inorderTraversal(root->right);
}
return ans;
}
};
2.模拟栈来实现递归
struct command{
string val;
TreeNode *Node;
command(string val,TreeNode *node):val(val),Node(node){}
};
class Solution {//中序遍历算法
public:
vector<int> ans;
vector<int> inorderTraversal(TreeNode* root) {
// //递归调用 但是返回值的问题需要解决 返回的是vector<int> 类型的数据
// /*
// vector<int> ans;
// if(root==NULL){
// return ans.push_back(NULL);
// }
// else{
// ans.push_back(root->val);
// ans.push_back(inorderTraversal(root->left));
// ans.push_back(inorderTranvesal(root->right));
// }
// */
// vector<int> ans;
// TreeNode *p=root;
// if(p==NULL){
// return ans;//
// }
// stack<TreeNode *> stackss;
// while(p!=NULL||!stackss.empty()){
// while(p!=NULL){
// stackss.push(p);
// p=p->left;//首先找到最左边的子节点;
// }
// if(!stackss.empty()){
// TreeNode *q=stackss.top();
// ans.push_back(q->val);
// stackss.pop();
// p=q->right;
// }
// }
// return ans;
// if(root){
// inorderTraversal(root->left);
// ans.push_back(root->val);
// inorderTraversal(root->right);
// }
// return ans;
if(root==NULL){
return ans;
}
stack<command> ss;
ss.push(command("go",root));
while(!ss.empty()){
command top=ss.top();
ss.pop();
if(top.val=="cout"){
ans.push_back(top.Node->val);
}
else{
if(top.Node->right!=NULL){
ss.push(command("go",top.Node->right));}
ss.push(command("cout",top.Node));
if(top.Node->left!=NULL){
ss.push(command("go",top.Node->left));}
}
}
return ans;
}
};
同理后续遍历采用新的方式也是可以实现:这里不再做详细的介绍了;
队列的内容;
主要是关于树的层序遍历和无权图的最短路径;
leetcode102:
关于树的层序遍历方式;
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
//使用队列的数据结构来存储相应的结点,每当有节点pop出去就向队尾中添加结点
//C++中队列的数据结构是Queue
vector<vector<int>> ans;
if(root==NULL){
return ans;
}
queue<TreeNode *> result;//首先将相应的root元素入队
result.push(root);
while(!result.empty()){
//构建一个行的队列,用来存储相应的队列中临时数据
vector<int> tempVector;
queue<TreeNode *> tempQueue;
while(!result.empty()){
TreeNode *front=result.front();
result.pop();
tempVector.push_back(front->val);
if(front->left!=NULL){
tempQueue.push(front->left);
}
if(front->right!=NULL){
tempQueue.push(front->right);
}
}
ans.push_back(tempVector);
result=tempQueue;
}
return ans;
}
};
leetcode103:层序遍历树,当时树的遍历方式是zip zap的方式Z的方式来遍历树
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
//方法相同还是使用队列的数据结构来进行存储相应的数据;
//设置一个flag来表示技术如何加入队列中
queue<TreeNode *> result;
vector<vector<int>> ans;
if(root==NULL){
return ans;
}
int flag=1;
result.push(root);
while(!result.empty()){
queue<TreeNode*> temp;
vector<int> tempVector;
while(!result.empty()){
TreeNode *top=result.front();
result.pop();
tempVector.push_back(top->val);
if(top->left!=NULL){
temp.push(top->left);
}
if(top->right!=NULL){
temp.push(top->right);
}
}
if(flag==1){
ans.push_back(tempVector);
flag=0;}
else{
reverse(tempVector.begin(),tempVector.end());
ans.push_back(tempVector);
flag=1;}
result=temp;}
return ans;
}
};