原题
给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。
输入格式
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤ 1 0 5 10^5 105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据,Next
是下一结点的地址。
输出格式
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
my answer
有一个测试超时
思路:定义一个字典,字典中的元素都是以"Address": "Data Next"
形式存储,然后通过首地址在字典中找到首元节点,再以首元节点的Next
在字典中寻找首元结点的直接后继。在顺链遍历的过程中,按照要求的反转的子链表的大小N
,每N
个节点为一组,每个节点以元组的形式存入到列表linklist_child
中,N
个节点元组组成的一个列表linklist_child
再放入一个大的列表linklist
中,如此循环。对于最后一组子链,可能节点的数目小于N
,对于这组子链不必进行反转。
当所有的节点按顺序、按组存放到linklist
中之后,遍历linklist
,每次取出一个子链表(子链表以列表为类型,里面存放着以元组为类型的节点信息),如果子链中结点的数目等于N
,从后往前输出节点信息;如果子链中结点的数目小于N
,不需要反转,直接按要求输出即可。
basicInfo = input().split()
dict_node = dict() # 定义一个空的字典,字典中以“节点的地址”为键,以“节点的值和下一个节点的地址”为值
for i in range(int(basicInfo[1])):
node = input()
dict_node[node[:5]] = node[6:] # 将每一个节点都存到字典中
linklist = [] # 定义一个空的列表,其中每个元素也为一个列表,每个元素代表要反转的子链表
linklist_child = [] # 该列表用于存储一个子链表,子链表中的节点信息在列表中用一个元组表示
pointer = basicInfo[0] # 定义一个“指针”,用于顺链查找
count = 0 # 计数器,每找到一个完整的子链表,count 归零
while pointer != '-1': # 当“指针”没有到达最后一个节点时
node_info = dict_node[pointer]
node_info_list = node_info.split()
node_info_list.insert(0, pointer)
linklist_child.append(tuple(node_info_list))
pointer = node_info_list[-1]
count += 1
if count == int(basicInfo[2]): # 如果子链表的节点数到达指定数目,计数器归零,将子链表添加到 linklist 中
count = 0
linklist.append(linklist_child.copy()) # 注意此处不能直接 append(linklist_child),因为在下一行要执行 linklist_child.clear()
linklist_child.clear()
# 循环完毕之后判断一下是否有剩余元素
if len(linklist_child) != 0:
linklist.append(linklist_child)
flag = False # 表示是否打印的不是第一行
for linklistChild in linklist:
if len(linklistChild) == int(basicInfo[2]): # 判断子链的结点数是否满足要求
index = -1
for i in linklistChild:
node = linklistChild[index]
if flag: # 如果打印的不是第一行,就打印该结点的地址(表示上一个结点的Next值)之后,换行,再打印该结点的Address、Data值
print(node[0])
print("{} {} ".format(node[0], node[1]), end='')
else: # 如果打印的是第一行,就把该结点的Address、Data值并排输出
print("{} {} ".format(node[0], node[1]), end='')
flag = True
index -= 1
else:
for node in linklistChild:
if flag:
print(node[0])
print("{} {} ".format(node[0], node[1]), end='')
else:
print("{} {} ".format(node[0], node[1]), end='')
flag = True
print("-1")