当前位置: 首页 > backend >正文

CD73.【C++ Dev】map和set练习题1(有效的括号、复杂链表的复制)

目录

1.有效的括号

分析

代码

提交结果

2.复杂链表的复制

分析

代码

提交结果

​编辑


1.有效的括号

之前在L11.【LeetCode题解】有效的括号文章用C语言写过,要求采用C++ STL优化以下代码:

typedef char STDataType;
typedef struct Stack
{STDataType* a;int top; int capacity;
}ST;void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){perror("malloc");return;}ps->capacity = 4;ps->top = 0;//top栈顶元素的下一个位置
}void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc");return;}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));//确保不越界ps->top--;
}STDataType STTop(ST* ps)//访问栈顶元素
{assert(ps);assert(!STEmpty(ps));//确保不越界return ps->a[ps->top - 1];
}bool isValid(char* s) 
{ST st;STInit(&st);while(*s){if (*s=='('||*s=='['||*s=='{'){STPush(&st,*s);}else{if (STEmpty(&st))return false;char top=STTop(&st);//注意STPop(&st);if ((*s==')'&&top !='(')||(*s==']'&&top !='[')||(*s=='}'&&top !='{'))return false;}s++;}bool ret=STEmpty(&st);STDestory(&st);return ret;
}

分析

上方代码手动实现了栈的各个操作,可以改用STL的stack<char>

class Solution {
public:bool isValid(string s) {stack<char> st;for (auto ch:s){if (ch=='('||ch=='['||ch=='{'){st.push(ch);}else{if (st.empty())return false;char top=st.top();st.pop();if ((ch==')'&&top !='(')||(ch==']'&&top !='[')||(ch=='}'&&top !='{'))return false;}}return st.empty();}
};

本题考察括号的匹配,匹配问题可以用map,那么if判断可以用map优化

map中存储正确的匹配:

map<char,char> mp;
//调用operator[]比用insert写起来方便
mp['(']=')';
mp['[']=']';
mp['{']='}';

简化if判断:

if (mp.count(ch))//如果ch能在map的所有key中能找到,就push
{st.push(ch);
}
else
{if (st.empty())return false;char top=st.top();st.pop();if (mp[top]!=ch)//左右括号不匹配,返回falsereturn false;
}

代码

class Solution {
public:bool isValid(string s) {stack<char> st;map<char,char> mp;//调用operator[]比用insert写起来方便mp['(']=')';mp['[']=']';mp['{']='}';for (auto ch:s){if (mp.count(ch))//如果ch能在map的所有key中能找到,就push{st.push(ch);}else{if (st.empty())return false;char top=st.top();st.pop();if (mp[top]!=ch)//左右括号不匹配,返回falsereturn false;}}return st.empty();}
};

提交结果

2.复杂链表的复制

之前在L34.【LeetCode题解】随机链表的复制(复杂链表的复制)文章用C语言写过,要求采用C++ STL优化以下代码:

struct Node* copyRandomList(struct Node* head) 
{struct Node* cur=head;//插入新节点while(cur){struct Node* newnode=(struct Node*)malloc(sizeof(struct Node));newnode->next=cur->next;newnode->val=cur->val;cur->next=newnode;cur=cur->next->next;}//设置randomcur=head;while(cur){struct Node* copy=cur->next;if (cur->random==NULL){copy->random=NULL;}else{copy->random=cur->random->next;//重要的一步}cur=cur->next->next;}struct Node* copy_head=NULL;struct Node* copy_tail=NULL;cur=head;while(cur){struct Node* copy=cur->next;struct Node* copy_next=copy->next;if (copy_head==NULL)//空链表尾插{copy_head=copy_tail=copy;}else//非空链表尾插{copy_tail->next=copy;copy_tail=copy_tail->next;//更新尾部}cur->next=copy_next;//恢复原链表cur=cur->next;}return copy_head;   
}

分析

首先复制链表,暂时`不处理random指针

if (head==nullptr)return nullptr;
Node* cur=head;//遍历要复制的链表
Node* copy=nullptr;
Node* copy_head=nullptr;//保存拷贝链表的头节点
for(;;)
{if (copy==nullptr){copy=new Node(cur->val);copy_head=copy;cur=cur->next;}else if (cur){copy->next=new Node(cur->val);copy=copy->next;cur=cur->next;}else//复制完毕break;
}

链表复制中比较难处理的是random指针指向的节点,处理方法: 用map提前存映射,让cur指向的节点和copy指向的节点一一对应

那么在设置random时:

解读图片: cur指向的节点的random的值为cur->random,指向的节点对应在新链表中的位置为map[cur->random],这下copy->random就好设置值了

那么可以边复制链表(不包含设置random指针)边设置map<Node*,Node*>:

if (head==nullptr)return nullptr;
Node* cur=head;//遍历要复制的链表
Node* copy=nullptr;
Node* copy_head=nullptr;//保存拷贝链表的头节点
map<Node*,Node*> mp;
for(;;)
{if (copy==nullptr){copy=new Node(cur->val);mp[cur]=copy;copy_head=copy;cur=cur->next;}else if (cur){copy->next=new Node(cur->val);copy=copy->next;mp[cur]=copy;cur=cur->next;}else//复制完毕break;
}

最后依据map的内容设置复制链表的指针:

//设置random
copy=copy_head;
cur=head;
while(copy)
{copy->random=mp[cur->random];cur=cur->next;copy=copy->next;
}

代码

class Solution {
public:Node* copyRandomList(Node* head) {if (head==nullptr)return nullptr;Node* cur=head;//遍历要复制的链表Node* copy=nullptr;Node* copy_head=nullptr;//保存拷贝链表的头节点map<Node*,Node*> mp;for(;;){if (copy==nullptr){copy=new Node(cur->val);mp[cur]=copy;copy_head=copy;cur=cur->next;}else if (cur){copy->next=new Node(cur->val);copy=copy->next;mp[cur]=copy;cur=cur->next;}else//复制完毕break;}//设置randomcopy=copy_head;cur=head;while(copy){copy->random=mp[cur->random];cur=cur->next;copy=copy->next;}return copy_head;}
};

提交结果

http://www.xdnf.cn/news/19407.html

相关文章:

  • Docker中Mysql容器忽略大小写
  • C语言————深入理解指针1(通俗易懂)
  • Linux-搭建NFS服务器
  • 【PyTorch】基于YOLO的多目标检测(一)
  • 【CNB.COOL】智能花卉分类系统 – 部署指北
  • 由题构造 嵌入汇编(汇编)
  • python调用豆包大模型给人脸生成卡通图像
  • 八大排序--快速排序
  • 福彩双色球第2025100期数据统计
  • hardhat 3 测试框架选择
  • linux系统学习(14.日志管理)
  • 华秋DFM检查PCB设计缺陷、一键导出Gerber、BOM、坐标文件
  • 第八章 光照
  • Qt QNetworkAccessManager 简述及例程
  • C++11——万能模板及完美转发
  • GMTapSDK 扩展使用文档
  • 【开题答辩全过程】以 基于springboot的垃圾分类管理系统为例,包含答辩的问题和答案
  • LSTM原理理解
  • 8.29学习总结
  • 大语言模型(LLM)简介与应用分享
  • Linux-数据库
  • 旅游景点库系统的设计与实现(代码+数据库+LW)
  • 力扣hot100:轮转数组(常规思路与三步反转讲解)(189)
  • mmaction安装的详细说明帖
  • 王立群《读史记-刘邦》读书笔记
  • 嵌入式C学习笔记之编码规范
  • 数学分析原理答案——第七章 习题12
  • AI大模型实战解析-RAG知识库+LangChain项目实战
  • Linux系统的进程管理
  • Unity3D Gizmos 调试可视化