package pers.lyt.java;
//题目
// 输入两个链表,找出它们的第一个公共结点。
//思路
// 蛮力法:遍历第一个链表的结点,每到一个结点,就在第二个链表上遍历每个结点,判断是否相等。
//时间复杂度为O(m*n),效率低;
// 使用栈:由于公共结点出现在尾部,所以用两个栈分别放入两个链表中的结点,从尾结点开始出栈
//比较。时间复杂度O(m+n),空间复杂度O(m+n)。
// 利用长度关系:计算两个链表的长度之差,长链表先走相差的步数,之后长短链表同时遍历,找到
//的第一个相同的结点就是第一个公共结点。
// 利用两个指针:一个指针顺序遍历list1和list2,另一个指针顺序遍历list2和list1,(这样
//两指针能够保证最终同时走到尾结点),两个指针找到的第一个相同结点就是第一个公共结点。
public class Offer52_FirstCommonNodesInLists {
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
/**
* 方法1:利用长度关系
*/
public ListNode findFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null)
return null;
int length1 = getLength(pHead1);
int length2 = getLength(pHead2);
int lengthDif = length1 - length2;
ListNode longList = pHead1;
ListNode shortList = pHead2;
if (lengthDif < 0) {
longList = pHead2;
shortList = pHead1;
lengthDif = -lengthDif;
}
for (int i = 0; i < lengthDif; i++)
longList = longList.next;
while (longList != null && longList != shortList) {
longList = longList.next;
shortList = shortList.next;
}
return longList; // 没有公共结点刚好是null
}
private int getLength(ListNode head) {
int len = 0;
while (head != null) {
len++;
head = head.next;
}
return len;
}
/**
* 方法2:两个指针,p1顺序遍历list1和list2;p2顺序遍历list2和list1;最终一定会相遇
*/
public ListNode findFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null)
return null;
ListNode p1 = pHead1;
ListNode p2 = pHead2;
while (p1 != p2) {
p1 = p1 == null ? pHead2 : p1.next;
p2 = p2 == null ? pHead1 : p2.next;
}
return p1;
}
}
52_FirstCommonNodesInLists
最新推荐文章于 2021-02-27 01:18:38 发布