4303 链表(哈希表)

1. 问题描述:

有若干个单链表,每个的长度都不小于 2,任意两个链表之间不存在公共节点。每个节点上都包含一个字符串。不同节点上包含的字符串不同。在这些单链表中,包含直接后继节点的节点数量为 q。给定这 q 个节点的相关信息,请你计算并输出单链表的具体数量以及每个单链表的头节点和尾节点包含的字符串。

输入格式

第一行包含一个整数 q。接下来 q 行,每行描述一个存在直接后继节点的节点的相关信息,包含两个字符串,分别表示该节点包含的字符串以及其直接后继节点包含的字符串。同一链表中的节点在输入中的相对顺序与在链表中的相对顺序一致。也就是说,如果节点 a 和节点 b 都在同一链表中,且都存在直接后继节点,那么在输入节点相关信息时,a 节点的信息一定比 b 节点的信息先输入。

输出格式

第一行输出一个整数 n,表示单链表的具体数量。接下来 n 行,每行输出两个由单个空格隔开的字符串,表示其中一个单链表的头节点和尾节点包含的字符串。不同链表的输出顺序随意。

数据范围

前三个测试点满足 1 ≤ q ≤ 10。
所有测试点满足 1 ≤ q ≤ 1000,节点字符串由大小写字母和数字组成,长度范围 [1,20]。

输入样例:

5
a b
d e
e f
b c
g h

输出样例:

3
a c
d f
g h
来源:https://www.acwing.com/problem/content/description/4306/

2. 思路分析:

首先我们需要读懂题目的意思,由题目可知输入的是当前节点和下一个节点的信息,字符串标识链表节点,我们需要求解出最终没有交集的单链表的数目,观察题目中的例子就很好理解了,所以我们需要找到每一个单链表的起点和终点,并且题目中规定了同一链表中的节点在输入中的相对顺序与在链表中的相对顺序一致,所以当前遍历的节点要不就是只有两个节点的单链表要不就是上一个链表的节点,所以找到链表的起点和终点即可。我们可以使用哈希表来记录起点-> 终点的键值对,方便后面枚举起点的时候判断当前是只有两个节点的单链表还是大于两个节点的单链表,如果是大于两个节点的单链表那么遍历找到链表的终点并且标记遍历过的节点已经被访问。

3. 代码如下:

class Solution:
    def process(self):
        n = int(input())
        # mp1记录起点->终点
        mp1 = dict()
        for i in range(n):
            s = input().split()
            start, end = s[0], s[1]
            mp1[start] = end
        count = 0
        # mp2记录已经访问过的节点, res记录单链表的起点和终点
        mp2, res = dict(), dict()
        for k, v in mp1.items():
            if v not in mp1 and k not in mp2:
                # 当前节点没有被访问过并且终点没有出边所以一定是只有两个节点的链表
                count += 1
                mp2[k] = 1
                mp2[v] = 1
                res[k] = v
            # 起点不能够已经被访问
            elif v in mp1 and k not in mp2:
                mp2[k] = 1
                mp2[v] = 1
                s = v
                # 找到当前当前链表的终点, 并且标记所有访问过的点
                while s in mp1:
                    s = mp1[s]
                    mp2[s] = 1
                count += 1
                res[k] = s
        print(count)
        for k, v in res.items():
            print(k, v)


if __name__ == '__main__':
    Solution().process()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值