链表相交节点优化:双指针差值法解析与实现
在数据结构与算法的学习过程中,链表是一种常见的线性数据结构。链表由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在某些场景下,两个链表可能会相交,即它们的某些节点是相同的。在LeetCode等编程竞赛平台中,链表相交节点问题是一个经典的面试题。
传统的解决方法是通过遍历两个链表,比较每个节点的值,直到找到第一个相同的节点。这种方法的时间复杂度为O(n+m),其中n和m分别是两个链表的长度。这种方法在链表长度较大时效率较低。
本文将介绍一种更高效的方法——双指针差值法,来寻找链表相交的节点。这种方法的时间复杂度为O(n+m),但空间复杂度更低,只需要常数级别的额外空间。
双指针差值法原理
双指针差值法的基本思想是利用两个指针分别遍历两个链表,通过调整指针的移动步长来找到相交节点。具体步骤如下:
1. 找到两个链表的长度,分别为len1和len2。
2. 计算两个链表长度的差值,记为diff。
3. 将较长的链表的指针向后移动diff个节点。
4. 同时移动两个指针,每次移动一个节点,直到两个指针相遇,即找到相交节点。
这种方法之所以有效,是因为两个指针在移动过程中,它们之间的距离始终是两个链表长度之差。当两个指针相遇时,它们必然在相交节点处。
代码实现
以下是一个使用双指针差值法寻找链表相交节点的Python代码实现:
python
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def get_intersection_node(headA, headB):
if not headA or not headB:
return None
lenA, lenB = 0, 0
pA, pB = headA, headB
计算两个链表的长度
while pA:
lenA += 1
pA = pA.next
while pB:
lenB += 1
pB = pB.next
计算长度差值
diff = abs(lenA - lenB)
将较长的链表的指针向后移动差值个节点
if lenA > lenB:
pA = headA
pB = headB
for _ in range(diff):
pA = pA.next
else:
pA = headB
pB = headA
for _ in range(diff):
pB = pB.next
同时移动两个指针,直到相遇
while pA and pB:
if pA == pB:
return pA
pA = pA.next
pB = pB.next
return None
测试代码
def create_linked_list(arr):
if not arr:
return None
head = ListNode(arr[0])
current = head
for value in arr[1:]:
current.next = ListNode(value)
current = current.next
return head
def print_linked_list(head):
current = head
while current:
print(current.val, end=" -> ")
current = current.next
print("None")
创建两个相交的链表
list1 = [1, 2, 3, 4, 5]
list2 = [0, 6, 7, 8]
intersection_node = 4
head1 = create_linked_list(list1)
head2 = create_linked_list(list2)
node = ListNode(intersection_node)
list2.next.next.next = node
print("List 1: ", end="")
print_linked_list(head1)
print("List 2: ", end="")
print_linked_list(head2)
寻找相交节点
intersection = get_intersection_node(head1, head2)
if intersection:
print("Intersection Node: ", intersection.val)
else:
print("No intersection found.")
总结
本文介绍了双指针差值法在寻找链表相交节点中的应用。这种方法具有时间复杂度低、空间复杂度低的优点,适用于处理链表相交问题。在实际应用中,我们可以根据具体场景选择合适的方法来解决问题。
Comments NOTHING