• C++ - map 的 例题


     前言

    本博客在 一下文章关于 map 和 set 讲解之下,对 map 当中的 operator[] ()函数的功能运用,感受 map 功能强大。

     

    349. 两个数组的交集 - 力扣(LeetCode)

    给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

    1. 示例 1
    2. 输入:nums1 = [1,2,2,1], nums2 = [2,2]
    3. 输出:[2]
    4. 示例 2
    5. 输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
    6. 输出:[9,4]
    7. 解释:[4,9] 也是可通过的

    法一: 

    我们可以,两个集合当中的内容都放进 两个 set 当中,第一个是 去重,第二是排序,好查找。然后,去两个set 一个一个遍历比较,有相同的就是交集。

    法二:

    还有比 法一 更好的方法,开始也都把两个集合放到 两个 set 当中。然后中序遍历保存结果,比如是下面两个结果:

    1. 1 3 5 7 9
    2. 3 5 6 7 8

     然后,遍历不再想上述一样暴力查找,而是:

    都从第一位置开始,值小的一方开始++,直到遍历到相同元素停止,找到交集:

     第一次找到 3  ,停止。然后两个指针同时++,都之下下一个元素位置。

    然后重复上述过程就可以找出交集。

    当然,还可以用上述方法寻找差集

     代码实现:

    1. class Solution {
    2. public:
    3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    4. set<int> s1(nums1.begin(),nums1.end());
    5. set<int> s2(nums2.begin(),nums2.end());
    6. vector<int> v;
    7. auto it1 = s1.begin();
    8. auto it2 = s2.begin();
    9. while(it1 != s1.end() && it2 != s2.end())
    10. {
    11. if(*it1 < *it2)
    12. {
    13. it1++;
    14. }
    15. else if(*it2 < *it1)
    16. {
    17. it2++;
    18. }
    19. else{
    20. v.push_back(*it1);
    21. ++it1;
    22. ++it2;
    23. }
    24. }
    25. return v;
    26. }
    27. };

     上述这种方法可以用在服务器当中:
     

     上述这种模型当中,手机等等终端经常和 服务器 进行数据的比对,比如判断交集以外的数据,当手机当中有 服务器当中没有的 数据的时候,就需要上传到 服务器当中。这些本质是都是一些数据比对。使用上述 用 set 的方式是非常好的方法。

     
    20. 有效的括号 - 力扣(LeetCode)

    给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

    有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。
    3. 每个右括号都有一个对应的相同类型的左括号。

     在上图当中可以感受一些 ,C++有了 map 之后 相比于 C 语言的是实现有多么好用。

    而且,对于 c 当中硬性的括号判断,C++当中map 只需要多增加几个结点就可以了。C中中硬性的括号判断很冗余。

     138. 复制带随机指针的链表 - 力扣(LeetCode)

     C语言当中的实现过程可以看下面这篇博客:
    赋值带随机指针的链表-CSDN博客

     以下是C++当中利用 map 的key 和 value 来实现的映射关系。

    1. class Solution {
    2. public:
    3. Node* copyRandomList(Node* head) {
    4. map CopyNodeMap; // key 值存储 原链表当中的结点
    5. // value 值存储 新链表当中结点
    6. // 两边位置相对一样
    7. Node* copyhead = nullptr, *copytail = nullptr;
    8. // 先构建新链表,构建 next 指针
    9. Node* cur = head;
    10. while(cur)
    11. {
    12. Node* copyNode = new Node(cur->val);
    13. if(copyhead == nullptr)
    14. {
    15. copyhead = copytail = copyNode;
    16. }
    17. else
    18. {
    19. copytail->next = copyNode;
    20. copytail = copytail->next;
    21. }
    22. // 添加新表和旧表映射关系
    23. CopyNodeMap[cur] = copytail;
    24. cur = cur->next;
    25. }
    26. // 新表当中 random赋值
    27. cur = head;
    28. Node* copyptr = copyhead;
    29. while(cur)
    30. {
    31. if(cur->random == nullptr)
    32. copyptr->random = nullptr;
    33. else
    34. copyptr->random = CopyNodeMap[cur->random];
    35. cur = cur->next;
    36. copyptr = copyptr->next;
    37. }
    38. return copyhead;
    39. }
    40. };

    环形链表 II

     

    给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

    不允许修改 链表。

    示例 1:

     

    输入:head = [3,2,0,-4], pos = 1
    输出:返回索引为 1 的链表节点
    解释:链表中有一个环,其尾部连接到第二个节点。
    
    1. class Solution {
    2. public:
    3. ListNode *detectCycle(ListNode *head) {
    4. set s;
    5. ListNode* lptr = head;
    6. while(lptr)
    7. {
    8. if(s.find(lptr) == s.end())
    9. {
    10. s.insert(lptr);
    11. }
    12. else
    13. {
    14. return lptr;
    15. }
    16. lptr = lptr->next;
    17. }
    18. return NULL;
    19. }
    20. };

  • 相关阅读:
    如何把照片转成pdf文件,支持合并转换
    JavaWeb篇_10——HttpServletRequest对象
    图文流程 Linux部署多个Mysql
    Metabase学习教程:模型-1
    python研发工程师面试准备一
    PostgreSQL的扩展(extensions)-常用的扩展-pg_pathman
    《持续交付:发布可靠软件的系统方法》- 读书笔记(七)
    Prompt进阶2:LangGPT(构建高性能Prompt策略和技巧)--最佳实践指南
    持续集成和持续部署
    3.1-OR59 字符串中找出连续最长的数字串
  • 原文地址:https://blog.csdn.net/chihiro1122/article/details/132891933