2021-07-21

本文探讨了多种链表操作的解决方案,包括找到两个链表的第一个公共节点、使用C++ STL中的unordered_map进行哈希表操作,以及复制带有随机指针的链表。通过哈希表实现寻找链表交点,利用insert和find方法高效查找。同时,介绍了如何在复制链表时处理随机指针,确保复制后的链表与原链表具有相同状态。此外,还涉及了C++中unordered_map的插入、查找和排序操作。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


Day_05:哈希表的练习

一、剑指 Offer 52. 两个链表的第一个公共节点(每日一题)

问题描述:
输入两个链表,找出它们的第一个公共节点。

如下面的两个链表:

在这里插入图片描述

在节点 c1 开始相交。

思路:利用哈希表来解决:unordered_set,先把链A装入哈希表中,再以此遍历链B,判断是否存在重复链。

代码如下(示例):

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unordered_set<ListNode *>st;//unordered_set:不存在重复元素
        while(headA!=NULL){
            st.insert(headA);
            headA=headA->next;
        }
        while(headB!=NULL){
            if(st.count(headB)){//判断是否存在headB
                return headB;
            }
            headB=headB->next;
        }
     return NULL;
    }
};

二.c++stl

unorder_map:哈希表,键值对
插入:emplace(key,value)

 for(int i=0;i<j;i++){
 	if(s[i][0]==w){
	up.emplace(s[i],score[i]);//在unordered_map中插入数据
	}
}

查找:find(key):找不到,返回值为end()
修改value: unordered_map mp;
mp[key]++;//key对应的value值加1
排序:需要转为vector来排序
排序代码如下(示例):

bool comp(const pair<string,int>& a, const pair<string,int> &b){//参数是pair类型
    //若value不相同,按value从大到小排;若相同,按key从小到大排
    return a.second != b.second?a.second>b.second:a.first<b.first;
}

//排序:map没有sort函数,需要转为vector来排序

vector<pair<string,int> > b;
for(auto &x:up){//遍历的代码
	b.push_back(x);//push_back插入vector
}
sort(b.begin(),b.end(),comp);
for(auto &a:b){
	cout<<a.first<<" "<<a.second<<endl;
}

三 复制带随机指针的链表

问题描述:
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

思路:
第一步:根据遍历到的原节点创建对应的新节点,每个新创建的节点是在原节点后面
在这里插入图片描述
第二步:设置新链表的随机指针
在这里插入图片描述

第三步:只要将两个链表分离开,再返回新链表就可以了
在这里插入图片描述

代码如下:

class Solution {
public:
    Node* copyRandomList(Node* head) {
       Node *t=head;
       if(t==NULL){
           return NULL;
       }
       while(t!=NULL){
           Node *temp=new Node(t->val);
            temp->next=t->next;
            t->next=temp;
            t=temp->next;   
       }
       t=head;
       Node *temp=head->next;
       while(t!=NULL){
           Node*r_p=t->random;
           if(r_p!=NULL){
               temp->random=r_p->next;
           }
            else{
                temp->random=NULL;
            }
            t=temp->next;
            if(t!=NULL){
                temp=t->next;   
            }
             
       }
       Node *rethead;
       t=head;
       rethead=temp=head->next;
       while(t!=NULL){
            t->next=temp->next;
            t=t->next;
            if(t!=NULL){
                temp->next=t->next;
                temp=t->next;
            }
            
       }
      return rethead;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值