NC66 两个链表的第一个公共结点
描述 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: 0n≤1000 要求:空间复杂度 O(1),时间复杂度 O(n)
思路:一、如果有公共节点,那么两链表的后面部分完全相同,所以可以从后往前遍历,直到两个不同。因为链表没法从后往前遍历,所以需要反转两个链表,之后两个反转链表从后往前遍历,用result记录当前节点,如果相等,将当前节点赋给result,如果不相等的,则result.next = None,然后再将这个公共链表反转。
二、如果有公共节点,那么两链表的后面部分完全相同,所以后面部门链表的长度是一样的,所以可以先遍历两个链表(也可以直接为了省时间用快指针遍历),分别记录两个链表的长度为l1、l2,然后计算长度差,如果l1更长,那么链表1先走l1-l2步,反之,l2先走l2-l1步,之后两个链表一起走,当两个链表值相同时返回当前节点。
方法二可能更简单,但是如果给的链表如果一个是{1,2,3,5,6,7},另一个为{2,4,5,6,7},这时候方法二返回2,方法一返回5,不知道2算不算公共节点,如果算,则方法二对,方法一错。如果不算,则方法二错,方法一对。
用的方法二测试通过了,但是看返回结果应该是方法一才是对的,所以说明不会给出我提到的测试样例
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
#
# @param pHead1 ListNode类
# @param pHead2 ListNode类
# @return ListNode类
#
class Solution:
def FindFirstCommonNode(self , pHead1 , pHead2 ):
# write code here
l1 = 0
l2 = 0
if (pHead1 == None) | (pHead2 == None):
return None
p1 = pHead1
p2 = pHead2
while (p1 != None) | (p2 != None):
if p1 == p2:
return p1
if p1 != None:
l1 += 1
p1 = p1.next
if p2 != None:
l2 += 1
p2 = p2.next
p1 = pHead1
p2 = pHead2
n = l1
if l1 > l2:
for i in range(l1-l2):
p1 = p1.next
n = l2
elif l2 > l1:
for j in range(l2-l1):
p2 = p2.next
for k in range(n):
if p1.val == p2.val:
return p1
p1 = p1.next
p2 = p2.next
return None