📜  打印成对的最大长度链(1)

📅  最后修改于: 2023-12-03 15:10:02.021000             🧑  作者: Mango

打印成对的最大长度链

介绍

给定一个由多个链表节点构成的链表,每个节点包含了两个值,分别为val和next。需要从里面选择出尽量多的节点,使得每个节点的val值均唯一,且组成的链表长度最大。最终需要打印出这些节点的val值。

思路

此问题可以转化为求有向无环图(DAG)中的最长路径。

  1. 首先将链表按照val的大小排序。
  2. 然后对于排序后的每个节点,使用动态规划来计算到此节点为止的最长链长度。具体地,对于每个节点,找到与其val小的节点,然后在它们作为起点的链中寻找最长的一条链。最终得到所有链的最大长度。
代码实现

以下是Python代码实现:

class ListNode:
    def __init__(self, val=0, nxt=None):
        self.val = val
        self.next = nxt

def print_max_length_chain(head: ListNode) -> None:
    # 首先将链表按照val的大小排序
    arr = []
    while head:
        arr.append(head)
        head = head.next
    arr.sort(key=lambda x: x.val)

    # 动态规划求最长链长度
    n = len(arr)
    dp = [1] * n  # 到每个节点的最长链长度
    prev = [-1] * n  # 每个节点最长链的前驱节点
    for i in range(n):
        for j in range(i):
            if arr[j].val < arr[i].val:
                if dp[j] + 1 > dp[i]:
                    dp[i] = dp[j] + 1
                    prev[i] = j

    # 获取最长链并输出
    max_len = max(dp)
    last_node = arr[dp.index(max_len)]
    chain = []
    while last_node:
        chain.append(str(last_node.val))
        last_node = arr[prev[dp.index(max_len)]]
        dp[dp.index(max_len)] -= 1
        max_len -= 1
    chain.reverse()
    print("->".join(chain))

# 测试代码
if __name__ == "__main__":
    head = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
    print_max_length_chain(head)  # 1->2->3->4->5

    head = ListNode(4, ListNode(1, ListNode(3, ListNode(2, ListNode(5)))))
    print_max_length_chain(head)  # 1->2->4->5

    head = ListNode(3, ListNode(2, ListNode(6, ListNode(4, ListNode(5, ListNode(1)))))) 
    print_max_length_chain(head)  # 1->2->3->6
性能分析

时间复杂度: $O(n^2)$

空间复杂度: $O(n)$

其中 $n$ 为链表长度。