1.方法一:将其中一个链表存放到集合里,然后一边遍历第二个链表,一边找集合里寻找,直到找到对应的节点就是所求。
public static Node FindFirstCommonNodeBySet(Node head1, Node head2)
{
if (head1 == null || head2 == null)
return null;
HashSet<Node> set = new HashSet<Node>();
//把一个列表的每个节点的地址放进哈希表里,
while (head1 != null)
{
set.Add(head1);
head1 = head1.next;
}
//遍历第二个链表,判断哈希表是否存在相同地址的节点
while (head2 != null)
{
if (set.Contains(head2))
return head2;
head2 = head2.next;
}
return null;
}
2.方法二:将两个链表分别入栈,然后两边比较栈顶节点,如果相同就出栈,不断循环,直到出现不同节点为止,最后一个相同节点就是所求。
public static Node FindFirstCommonNodeByStack(Node head1, Node head2)
{
if (head1 == null || head2 == null)
return null;
Stack<Node> stack = new Stack<Node>();
Stack<Node> stack2 = new Stack<Node>();
//链表节点依次进栈
while (head1 != null)
{
stack.Push(head1);
head1 = head1.next;
}
while(head2 != null)
{
stack2.Push(head2);
head2 = head2.next;
}
//当两边栈顶节点相同时,两边同时出栈,直到不同为止
Node node = null;
while (stack.Count > 0 && stack2.Count > 0)
{
if (stack.Peek() == stack2.Peek())
{
node = stack.Pop();
stack2.Pop();
}
else
break;
}
return node;
}
3.方法三:将链表A和B拼接成AB和BA,这样子相同的节点会出现在相同位置。然后一起遍历AB和BA,直到找到相同节点就是所求。
我们不必真的新建两个链表AB、BA,只需要在遍历的时候把链表拼接即可。
public static Node FindFirstCommonNodeByMerge(Node head1, Node head2)
{
if (head1 == null || head2 == null)
return null;
//将两个链表拼接,然后分别遍历直到找到共同点,就是所求
Node temp1 = head1;
Node temp2 = head2;
while(temp1 != temp2)
{
temp1 = temp1.next;
temp2 = temp2.next;
if (temp1 != null || temp2 != null) //两个指针都到链表末尾就停下,防止无限循环
{
if (temp1 == null)
temp1 = head2;
if (temp2 == null)
temp2 = head1;
}
}
return temp1;
}
4.方法四:先计算两个链表长度的差值K,然后长的链表的头指针先走K步,然后再一起遍历,第一个相同节点就是所求节点。
public static Node FindFirstCommonNodeByLength(Node head1, Node head2)
{
if (head1 == null || head2 == null)
return null;
Node temp1 = head1;
Node temp2 = head2;
int count1 = 1;
int count2 = 1;
//分别遍历两个链表获取长度
while(temp1.next != null)
{
count1++;
temp1 = temp1.next;
}
while(temp2.next != null)
{
count2++;
temp2 = temp2.next;
}
//获取长度差值
int len = count1 > count2 ? count1 - count2 : count2 - count1;
//长的先走len步
if(count1 > count2)
{
int num = 0;
while(num < len)
{
head1 = head1.next;
num++;
}
}
if(count2 > count1)
{
int num = 0;
while(num < len)
{
head2 = head2.next;
num++;
}
}
//一起遍历直到找到共同节点
while(head1 != head2)
{
head1 = head1.next;
head2 = head2.next;
}
return head1;
}