题目:
小明是一名间谍,他需要将情报数据(由多组数字组成,每一组有多个小于10的正整数)编码后传回总部。编码算法是这样的:针对一组数字,做逆序倒排,然后顺序打乱分成多行,每一行放一个数。再给每个数增加一个数字,说明下一个数的在第几行。请写出解码算法,将编码后的多行数据解码成原始的数字。
举例:比如一组原始数据12345,逆序成54321。再拆成多行,加上下一个数的行数信息,如果是最后一个数,行数信息为0,得到:
4 2
3 4
1 0
2 3
5 1
解码算法就是将上面的5行数据解码成12345。
提示:将每一行数据做为一个链表节点。
思路
菜鸟保命说明:不确保是最优方法,代码写的也不优雅,也不确定能通过全部案例,力扣上没有原题,我也没办法测55~
题目分两步:
- 生成子链表
- 合并子链表
上代码
class LinkNode(object):
def __init__(self, val=0):
self.val = val
self.next = None
# 生成子链表函数
# 返回链表 head 和 end
def linkFn(num, idx):
# num 这个数 在 ll数组的索引为idx
dummy = LinkNode(num)
n_idx = num[1]
cur = dummy
while n_idx != 0 and vis[n_idx - 1] == 0:
vis[n_idx - 1] = 1
cur.next = LinkNode(ll[n_idx - 1])
cur = cur.next
n_idx = ll[n_idx - 1][1]
return dummy, cur
# 这是测试用例
# ll = [[6,3], [9, 4], [7, 0], [3, 5], [2, 1]] # >> 76239
# ll = [[2, 2], [6,3], [7, 4], [2, 5], [8, 6], [2, 0]] # >> 282762
ll = [[8, 0], [5, 1], [6,2], [4,3]] # >> 8564
vis = [0] * len(ll)
h = []
e = []
h_idx = []
e_idx = []
for idx, i in enumerate(vis):
if vis[idx] == 0:
vis[idx] = 1
head, end = linkFn(ll[idx], idx)
h.append(head)
e.append(end)
h_idx.append(idx+1)
# 生成两条以上链表时,合并链表
if len(h) > 1: #生成两条链表的
for i in range(len(h)):
end = e[i]
if end.val[1] == 0: #这是终点
continue
else:
end_idx = end.val[1] #这条链表要连接的另一条链表的head的位置
end.next = h[h_idx.index(end_idx)] # 头尾相连
true_head = h[i]
else:
true_head = h[0]
res = []
while true_head:
res.append(true_head.val[0])
true_head = true_head.next
res.reverse()
print(res)