题目
输入两个链表,找出它们的第一个公共节点。
public static class ListNode{
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
分析
首先遍历两链表的长度。在第二次遍历的时候,在较长的链表上先走若干步,步数为两链表之差的绝对值,接着同时在两个链表遍历,找到的第一个相同的节点就是它们的第一个公共节点。
放码
public class FindTheSameNode {
public ListNode find(ListNode head1, ListNode head2) {
int length1 = count(head1);
int length2 = count(head2);
int diff = Math.abs(length1 - length2);
ListNode pLong = length1 > length2 ? head1 : head2,
pShort = length1 > length2 ? head2 : head1;
while(diff > 0) {
pLong = pLong.next;
diff--;
}
while(pLong != null && pShort != null
&& pLong != pShort) {
pLong = pLong.next;
pShort = pShort.next;
}
return pLong == pShort ? pLong : null;
}
public int count(ListNode head) {
int result = 0;
ListNode p = head;
while(p != null) {
result++;
p = p.next;
}
return result;
}
}
测试
import static org.junit.Assert.*;
import org.junit.Test;
import com.lun.util.SinglyLinkedList.ListNode;
public class FindTheSameNodeTest {
private static ListNode list1;
private static ListNode list2;
private static ListNode same;
static {
same = new ListNode(6);
same.next = new ListNode(7);
list1 = new ListNode(1);
list1.next = new ListNode(2);
list1.next.next = new ListNode(3);
list1.next.next.next = same;
list2 = new ListNode(4);
list2.next = new ListNode(5);
list2.next.next = same;
}
@Test
public void testFind() {
FindTheSameNode fn = new FindTheSameNode();
assertEquals(6, fn.find(list1, list2).val);
assertEquals(same, fn.find(list1, list2));
}
@Test
public void testCount() {
FindTheSameNode fn = new FindTheSameNode();
assertEquals(5, fn.count(list1));
assertEquals(4, fn.count(list2));
}
}