map和set题目练习

一、习题一:随机链表的复制

1.1题目详情

1.2思路

在没有学习map和set之前,解决这道题最大的问题就在于无法建立原链表与拷贝链表的映射关系,只能通过在原链表每个节点后面新建一个新的链表来进行节点间的对应,而学习了map之后,就可以选用map<Node*,Node*>来建立两个链表之间的映射关系了

在map中,我们对[]进行了重载,可以实现没有对应key的节点时插入节点并对该处节点的value进行操作,有key节点的时候直接对key对应的value进行操作

综上,我们可以选择如下实现思路:

①复制一个新的链表

②创建一个map对象,利用它来创建原链表与新链表之间的映射关系

③更新随机因子random

1.3代码实现

①基本版

/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;}
};
*/class Solution {
public:Node* copyRandomList(Node* head) {map<Node*,Node*> m1;//复制链表Node* cur=head;Node* copy_n=nullptr;Node* c_cur=copy_n;while(cur){if(copy_n==nullptr){c_cur=new Node(cur->val);copy_n=c_cur;cur=cur->next;}else{c_cur->next=new Node(cur->val);c_cur=c_cur->next;cur=cur->next;}}//遍历,在map中建立一一映射关系cur=head;c_cur=copy_n;while(cur){m1[cur]=c_cur;//确定不会在map里有c_cur=c_cur->next;cur=cur->next;}//再次遍历,对随机值random进行更新cur=head;c_cur=copy_n;while(cur){if(cur->random==nullptr)c_cur->random=nullptr;else{c_cur->random=(m1.find(cur->random))->second;}c_cur=c_cur->next;cur=cur->next;}return copy_n;}
};

②改善版:映射关系的建立可以和链表的复制一同进行

/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;}
};
*/class Solution {
public:Node* copyRandomList(Node* head) {map<Node*,Node*> m1;//复制链表,其中copy_n起头节点作用,c_cur起尾节点作用Node* cur=head;Node* copy_n=nullptr;Node* c_cur=nullptr;while(cur){//头尾节点指向一起if(copy_n==nullptr){copy_n=new Node(cur->val);c_cur=copy_n;}//尾节点往后走else{c_cur->next=new Node(cur->val);c_cur=c_cur->next;}//为原链表与循环链表建立联系(嵌套在循环里)m1[cur]=c_cur;cur=cur->next;}//循环设置复制链表randomcur=head;c_cur=copy_n;while(cur){if(cur->random==nullptr)c_cur->random=nullptr;else//c_cur->random=(m1.find(cur->random))->second;//m1[cur->random]本身就返回second的值,且一定存在cur->randomc_cur->random=m1[cur->random];c_cur=c_cur->next;cur=cur->next;}return copy_n;}
};

二、习题二:判断是否循环链表

2.1题目详情

2.2思路

未学习map和set之前,我们使用了快慢指针的方式来解决这道题,但快慢指针的应用意味着我们需要进行循环必定相遇的求证,证明过程并不简单;但现在有了map和set,我们就可以选择直接插入节点到set中,因为set的insert会返回一个可以证明插入是否有效的

pair<iterator,bool>

利用这个bool我们可以轻易得出答案

2.3代码实现

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:bool hasCycle(ListNode *head) {ListNode *tmp=head;set<ListNode*> sl;while(tmp){if(!(sl.insert(tmp).second))return true;tmp=tmp->next;}return false;}
};

2.补:关于异地容灾备份

我们手机上的云存储其实对应的是一个数据同时存储在手机和服务器上,当在手机上删除了备份过的内容,服务器与手机进行同步服务的时候会自动把删除了的内容复原回去;

但是数据实在服务器上存储,服务器也是电脑,也有可能损坏,所以为了保证数据的安全性,有了数据容灾备份,采用一原本,多副本的方式彼此间进行同步

三、前k个高频单词

3.1题目详情

3.2思路

之前题目一的练习我们已经知道了map中重载[]的用法,在这里我们可以利用重载后的[]快速得到单词与单词出现次数的映射关系

有了映射关系以后,我们只需要设法通过次数对pair进行排序即可得到前k个需要的单词,可以在仿函数中书写逻辑,再调用系统函数sort

因为返回值是一个vector<string>类型的值,所以我们需要把map中的单词拷贝到vector中,此时我们距离成功只差一步,那就是按照字典序排序

那么我们就这么思考怎么排吗?要知道map中我们其实已经是按照key的字典序排列的,可不可以不消耗更多时间呢?

问题可以从sort上解决,因为sort的底层是快排与堆排结合,既然有快排,那么排序完以后就会变得不稳定,所以

①可以采用稳定排序stable_sort

②可以在仿函数中进行比较逻辑的特殊设定,让出现次数相同时按照字典序排序,以此来保证稳定

综上,我们可以得出思路:

①创建map对象,for循环建立映射关系

②补充仿函数逻辑,将其传入sort,并用sort进行次数的比较的出前k个单词

③把前k个单词放到一个新的vector中

3.2补:pair的比较大小

pair之间其实也支持比较大小,比如“<”符号,会先看first小不小,如果first小的话那这个pair就小;如果first大于等于的话会看second小不小,seconde小的话也会小

例如:

pair<int,int> p1=make_pair(5,7);pair<int,int> p2=make_pair(8,6);p1<p2;//p1的first比p2小,所以应该返回truep2<p1;//p2的first比p1大,所以要看p2的second,而p2的second比p1小,所以也返回true

通过这个例子不难看出,除非在特殊情况,否则最好不要去用pair本身自带的比较逻辑,因为与我们日常思维方式不符合

3.3代码实现

①使用stable_sort稳定排序

struct Compare
{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){//排降序return p1.second>p2.second;}
};class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {//创建map,建立单词出现顺序和次数的联系map<string,int> m;for(const auto& e:words){m[e]++;}//排序,提取出排名前几的单词vector<pair<string,int>> v_p;for(const auto& e:m){v_p.push_back(e);}//使用相对位置不改变的sort来确保字典序排序stable_sort(v_p.begin(),v_p.end(),Compare());vector<string> s;for(size_t i=0;i<k;i++){s.push_back(v_p[i].first);}return s;}
};

②修改仿函数逻辑保持稳定

struct Compare
{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){//排降序return p1.second>p2.second||(p1.second==p2.second&&p1.first<p2.first);}
};class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {//创建map,建立单词出现顺序和次数的联系map<string,int> m;for(const auto& e:words){m[e]++;}//排序,提取出排名前几的单词vector<pair<string,int>> v_p(m.begin(),m.end());//使用相对位置不改变的sort来确保字典序排序sort(v_p.begin(),v_p.end(),Compare());vector<string> s;for(size_t i=0;i<k;i++){s.push_back(v_p[i].first);}return s;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hw亮度省电

1. 亮度控制策略 /decompile-hw/decompile/app/HwPowerGenieEngine3/src/main/res/xml/backlight_policy.xml <?xml version"1.0" encoding"utf-8"?> 2 <backlight_policy xmlns:android"http://schemas.android.com/apk/res/android&qu…

C语言入门(一):A + B _ 基础输入输出

前言 本专栏记录C语言入门100例&#xff0c;这是第&#xff08;一&#xff09;例。 目录 一、【例题1】 1、题目描述 2、代码详解 二、【例题2】 1、题目描述 2、代码详解 三、【例题3】 1、题目描述 2、代码详解 四、【例题4】 1、题目描述 2、代码详解 一、【例…

【21天学习AI底层概念】day8 什么是类意识?

类意识&#xff08;Quasi-Consciousness&#xff09; 是一个用来描述人工智能或复杂系统表现出的类似意识的行为或特性的概念。虽然这种系统不具备真正的意识&#xff08;即主观体验、情感和自我觉知&#xff09;&#xff0c;但在外部表现上&#xff0c;它们可能表现出与有意识…

Docker 镜像源 阿里镜像源限制后其他镜像源

要在Docker中修改镜像源&#xff0c;你需要编辑或创建Docker的配置文件来指定新的镜像源地址。以下是如何为Docker配置中国镜像源的步骤&#xff1a; 找到或创建Docker的配置文件daemon.json。 在Linux系统中&#xff0c;该文件通常位于/etc/docker/目录下。 编辑daemon.jso…

渗透测试学习笔记(五)网络

一.IP地址 1. IP地址详解 ip地址是唯一标识&#xff0c;一段网络编码局域网&#xff08;内网&#xff09;&#xff1a;交换机-网线-pcx.x.x.x 32位置2进制&#xff08;0-255&#xff09; IP地址五大类 IP类型IP范围A类0.0.0.0 到 127.255.255.255B类128.0.0.0 到191.255.25…

《自制编译器》--青木峰郎 -读书笔记 编译hello

在该书刚开始编译hello.cb时就遇到了问题。 本人用的是wsl&#xff0c;环境如下&#xff0c; 由于是64位&#xff0c;因此根据书中的提示&#xff0c;从git上下载了64位的cb编译器 cbc-64bit 问题一: 通过如下命令编译时,总是报错。 cbc -Wa,"--32" -Wl,"-…

LruCache(本地cache)生产环境中遇到的问题及改进

问题&#xff1a;单机qps增加时请求摘要后端&#xff0c;耗时也会增加&#xff0c;因为超过了后端处理能力&#xff08;最大qps&#xff0c;存在任务堆积&#xff09;。 版本一 引入LruCache。为了避免数据失效&#xff0c;cache数据的时效性要小于摘要后端物料的更新时间&…

jedis使用及注意事项

Jedis Jedis 是一个 Java 客户端&#xff0c;用于与 Redis 数据库进行交互。它提供了一系列简单易用的 API&#xff0c;使得在 Java 应用程序中使用 Redis 变得非常方便。以下是 Jedis 的使用方法及一些注意事项。 Jedis的优势 Lettuce客户端及Jedis客户端比较如下&#xff1a;…

CSDN博客:如何使用Python的`datasets`库转换音频采样率

CSDN博客&#xff1a;如何使用Python的datasets库转换音频采样率 什么是采样率&#xff1f;代码用途&#xff1a;调整音频数据的采样率完整代码示例代码详解运行结果&#xff08;示例&#xff09;总结 在这篇文章中&#xff0c;我们将学习如何使用Python的datasets库对音频数据…

浏览器执行机制

主线程 任务1&#xff0c;任务2 微队列微队列任务1&#xff0c; 微队列任务2延时队列延时队列任务1&#xff0c; 延时队列任务2交互队列.... 事件循环的工作原理 主线程执行同步任务&#xff1a; 主线程首先执行所有同步任务&#xff08;即栈中的任务&#xff09;。这些任务会…

Java 基础知识——part 4

8.成员方法&#xff1a;Java中必须通过方法才能对类和对象的属性操作&#xff1b;成员方法只在类的内部声明并加以实现。一般声明成员变量后再声明方法。 9.方法定义 方法的返回值是向外界输出的信息&#xff0c;方法类型和返回值类型同&#xff1b;返回值通过return返回&…

设计模式12:抽象工厂模式

系列总链接&#xff1a;《大话设计模式》学习记录_net 大话设计-CSDN博客 参考&#xff1a; C设计模式&#xff1a;抽象工厂模式&#xff08;风格切换案例&#xff09;_c 抽象工厂-CSDN博客 1.概念 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是软件设计…

【YashanDB知识库】kettle同步大表提示java内存溢出

【问题分类】数据导入导出 【关键字】数据同步&#xff0c;kettle&#xff0c;数据迁移&#xff0c;java内存溢出 【问题描述】kettle同步大表提示ERROR&#xff1a;could not create the java virtual machine! 【问题原因分析】java内存溢出 【解决/规避方法】 ①增加JV…

适配体技术在新药发现中的应用

适配体筛选技术在新药发现中的具体应用 适配体筛选技术&#xff0c;特别是SELEX&#xff08;Systematic Evolution of Ligands by Exponential Enrichment&#xff0c;指数富集的配体系统进化技术&#xff09;&#xff0c;在新药发现中扮演着至关重要的角色。这种技术能够从庞…

C/S软件授权注册系统(Winform+WebApi+.NET8+EFCore版)

适用软件&#xff1a;C/S系统、Winform桌面应用软件。 运行平台&#xff1a;Windows .NETCore&#xff0c;.NET8 开发工具&#xff1a;Visual Studio 2022&#xff0c;C#语言 数据库&#xff1a;Microsoft SQLServer 2012&#xff0c;Oracle 21c&#xff0c;MySQL8&#xf…

go语言使用websocket发送一条消息A,持续接收返回的消息

在Go语言中实现一个WebSocket客户端&#xff0c;可以使用gorilla/websocket这个非常流行的库来处理WebSocket连接。下面是一个简单的示例&#xff0c;展示了如何创建一个WebSocket客户端&#xff0c;向服务器发送消息"A"&#xff0c;并持续接收来自服务器的响应。 首…

监控易 IDC 数据中心一体化智能运维平台:新质生产力的典范

一、引言 在当今数字化飞速发展的时代&#xff0c;IDC 数据中心作为信息产业的核心基础设施&#xff0c;其稳定、高效运行对于企业和社会的重要性不言而喻。随着数据量的爆炸式增长和业务复杂度的提升&#xff0c;传统的运维模式已难以满足需求&#xff0c;数据中心面临着诸多挑…

活着就好20241218

亲爱的朋友们&#xff0c;大家早上好&#xff01;&#x1f31e; 今天是18号&#xff0c;星期三&#xff0c;2024年12月的第十八天&#xff0c;同时也是第50周的第九天&#xff0c;农历甲辰[龙]年十一月初十四日。在这晨光初照的美丽时刻&#xff0c;愿那温柔而灿烂的阳光轻轻洒…

busybox学习——简单介绍

文章目录 简介官网源码目录结构构建 简介 BusyBox 将许多具有共性的小版本的UNIX工具结合到一个单一的可执行文件。这样的集合可以替代大部分常用工具比如的GNU fileutils &#xff0c; shellutils等工具&#xff0c;BusyBox提供了一个比较完善的环境&#xff0c;可以适用于任…

C++常见面试题-初级2

1. C和C有什么区别&#xff1f; C是面向对象的语言&#xff0c;而C是面向过程的语言&#xff1b;C引入new/delete运算符&#xff0c;取代了C中的malloc/free库函数&#xff1b;C引入引用的概念&#xff0c;而C中没有&#xff1b;C引入类的概念&#xff0c;而C中没有&#xff1…