劍指Offer 兩個鏈表的第一個公共結點
阿新 • • 發佈:2018-02-13
color code wal get www ret 時間復雜度 common 相同
題目鏈接:兩個鏈表的第一個公共結點
思路:如果兩個鏈表有公共結點,則第一個公共結點以及之後的所有結點都是重合的,即至少它們的尾結點是重合的。因為兩個鏈表長度不一定相等,所以同步遍歷時不能保證兩個鏈表同時到達尾結點。假設一個鏈表比另一個多k個結點,先在長的鏈表上遍歷k個結點即尾部對齊,再同步遍歷,保證同時到達尾結點,即同時到達第一個公共結點。也就是說,同步遍歷時第一個相同結點就是第一個公共結點。
步驟:
1 如果兩個鏈表至少有一個是空,則返回null。
2 分別獲取兩個鏈表的長度len1和len2。
3 通過比較兩個鏈表的長度來獲取長度差k,並使長鏈表遍歷k個結點。
4 通過同步遍歷來查找第一個公共結點,如果查找到公共結點,則返回該結點。
5 返回null。
時間復雜度:O(len1+len2)。
Java代碼:
1 /*
2 public class ListNode {
3 int val;
4 ListNode next = null;
5
6 ListNode(int val) {
7 this.val = val;
8 }
9 }*/
10 public class Solution {
11 public ListNode FindFirstCommonNode(ListNode list1, ListNode list2) {
12 // 如果兩個鏈表至少有一個是空,則返回null
13 if (list1 == null || list2 == null) {
14 return null;
15 }
16
17 // 分別獲取兩個鏈表的長度len1和len2
18 int len1 = getListLength(list1);
19 int len2 = getListLength(list2);
20
21 // 通過比較兩個鏈表的長度來獲取長度差k,並使長鏈表遍歷k個結點
22 if (len1 > len2) {
23 list1 = walkSteps(list1, len1 - len2);
24 } else {
25 list2 = walkSteps(list2, len2 - len1);
26 }
27
28 // 通過同步遍歷來查找第一個公共結點,如果查找到公共結點,則返回該結點
29 while (list1 != null) {
30 if (list1 == list2) {
31 return list1;
32 }
33
34 list1 = list1.next;
35 list2 = list2.next;
36 }
37
38 // 返回null
39 return null;
40 }
41
42 // 獲取鏈表長度
43 private int getListLength(ListNode list) {
44 int len = 1;
45 while (list.next != null) {
46 list = list.next;
47 len++;
48 }
49
50 return len;
51 }
52
53 // 獲取當前結點走了k步之後的結點
54 private ListNode walkSteps(ListNode list, int k) {
55 while (k-- > 0) {
56 list = list.next;
57 }
58
59 return list;
60 }
61 }
參考資料
[編程題]兩個鏈表的第一個公共結點
《2017年數據結構聯考復習指導》P46-47
劍指Offer 兩個鏈表的第一個公共結點