题目描述
输入两个链表,找出它们的第一个公共结点。
由于是单链表,所以可以发现从第一个公共节点开始,后面的结点都是相同的,一种思路是从两个链表的尾部开始遍历,直到发现最后一个相同的结点为止,那么这最后一个相同的结点是单链表的角度看就是两个链表的第一个公共节点了。还有一种思路是不需要从尾部开始遍历,毕竟从尾部遍历单链表的话还得使用反转链表的方法进行操作,首先计算出两个链表的长度,让更长的那个单链表先移动两个链表长度差值个位置,然后两个链表同时移动,从更短的那个链表的第一个位置开始遍历,两个链表都往后移动,当发现第一个相同的结点的值的时候,那么该节点就是第一个公共节点了。
package com.gpl.offer.jianzhi; /** * Created by gpl on 2016/9/1. */ public class FirstCommonListNode { static class ListNode{ int val; ListNode next = null; public ListNode(int val){ this.val = val; } } public static ListNode findFirstCommonListNode(ListNode head1,ListNode head2){ int list1 = 0; int list2 = 0; ListNode tempNode = head1; while(tempNode != null){ list1++; tempNode = tempNode.next; } tempNode = head2; while(tempNode != null){ list2++; tempNode = tempNode.next; } int listDif = list1 - list2; ListNode longListhead = null; ListNode shortListhead = null; if(listDif >= 0){ longListhead = head1; shortListhead = head2; }else{ longListhead = head2; shortListhead = head1; listDif = -listDif; } for(int i=0;i<listDif;i++){ longListhead = longListhead.next; } // while(shortListhead != null && longListhead != null){ // if(shortListhead.val == longListhead.val) // return longListhead; // } // return null; while(shortListhead != null && longListhead != null && shortListhead.val != longListhead.val){ shortListhead = shortListhead.next; longListhead = longListhead.next; } return longListhead; } public static void main(String[] args){ ListNode pHead1 = new ListNode(1); ListNode node1 = new ListNode(2); ListNode node2 = new ListNode(5); ListNode node3 = new ListNode(6); ListNode node4 = new ListNode(7); pHead1.next = node1; node1.next = node2; node2.next = node3; node3.next = node4; ListNode pHead2 = new ListNode(4); ListNode node5 = new ListNode(5); ListNode node6 = new ListNode(6); ListNode node7 = new ListNode(7); pHead2.next = node5; node5.next = node6; node6.next = node7; ListNode result = FirstCommonListNode.findFirstCommonListNode(pHead1,pHead2); System.out.println(result.val); } }