diff --git a/lcci/02.07.Intersection of Two Linked Lists/README.md b/lcci/02.07.Intersection of Two Linked Lists/README.md index fc268de03e30a..677f0cd932bf1 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/README.md +++ b/lcci/02.07.Intersection of Two Linked Lists/README.md @@ -9,7 +9,15 @@ ## 解法 -### 方法一 +### 方法一:双指针 + +我们使用两个指针 $a$, $b$ 分别指向两个链表 $headA$, $headB$。 + +同时遍历链表,当 $a$ 到达链表 $headA$ 的末尾时,重新定位到链表 $headB$ 的头节点;当 $b$ 到达链表 $headB$ 的末尾时,重新定位到链表 $headA$ 的头节点。 + +若两指针相遇,所指向的结点就是第一个公共节点。若没相遇,说明两链表无公共节点,此时两个指针都指向 `null`,返回其中一个即可。 + +时间复杂度 $O(m+n)$,其中 $m$ 和 $n$ 分别是链表 $headA$ 和 $headB$ 的长度。空间复杂度 $O(1)$。 @@ -23,11 +31,11 @@ class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: - cur1, cur2 = headA, headB - while cur1 != cur2: - cur1 = headB if cur1 is None else cur1.next - cur2 = headA if cur2 is None else cur2.next - return cur1 + a, b = headA, headB + while a != b: + a = a.next if a else headB + b = b.next if b else headA + return a ``` ```java @@ -44,12 +52,12 @@ class Solution: */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - ListNode cur1 = headA, cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 == null ? headB : cur1.next; - cur2 = cur2 == null ? headA : cur2.next; + ListNode a = headA, b = headB; + while (a != b) { + a = a == null ? headB : a.next; + b = b == null ? headA : b.next; } - return cur1; + return a; } } ``` @@ -66,13 +74,12 @@ public class Solution { class Solution { public: ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) { - ListNode* cur1 = headA; - ListNode* cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1->next : headB; - cur2 = cur2 ? cur2->next : headA; + ListNode *a = headA, *b = headB; + while (a != b) { + a = a ? a->next : headB; + b = b ? b->next : headA; } - return cur1; + return a; } }; ``` @@ -86,20 +93,44 @@ public: * } */ func getIntersectionNode(headA, headB *ListNode) *ListNode { - cur1, cur2 := headA, headB - for cur1 != cur2 { - if cur1 == nil { - cur1 = headB + a, b := headA, headB + for a != b { + if a == nil { + a = headB } else { - cur1 = cur1.Next + a = a.Next } - if cur2 == nil { - cur2 = headA + if b == nil { + b = headA } else { - cur2 = cur2.Next + b = b.Next } } - return cur1 + return a +} +``` + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null { + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; + } + return a; } ``` @@ -118,16 +149,42 @@ func getIntersectionNode(headA, headB *ListNode) *ListNode { * @return {ListNode} */ var getIntersectionNode = function (headA, headB) { - let cur1 = headA; - let cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1.next : headB; - cur2 = cur2 ? cur2.next : headA; + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; } - return cur1; + return a; }; ``` +```swift +/** + * Definition for singly-linked list. + * public class ListNode { + * public var val: Int + * public var next: ListNode? + * public init(_ val: Int) { + * self.val = val + * self.next = nil + * } + * } + */ + +class Solution { + func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? { + var a = headA + var b = headB + while a !== b { + a = a == nil ? headB : a?.next + b = b == nil ? headA : b?.next + } + return a + } +} +``` + diff --git a/lcci/02.07.Intersection of Two Linked Lists/README_EN.md b/lcci/02.07.Intersection of Two Linked Lists/README_EN.md index bd2ee8ba86223..c0fdf4bccf0f7 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/README_EN.md +++ b/lcci/02.07.Intersection of Two Linked Lists/README_EN.md @@ -47,7 +47,15 @@ ## Solutions -### Solution 1 +### Solution 1: Two Pointers + +We use two pointers $a$ and $b$ to point to two linked lists $headA$ and $headB$ respectively. + +We traverse the linked lists simultaneously. When $a$ reaches the end of the linked list $headA$, it is repositioned to the head node of the linked list $headB$. When $b$ reaches the end of the linked list $headB$, it is repositioned to the head node of the linked list $headA$. + +If the two pointers meet, the node they point to is the first common node. If they don't meet, it means that the two linked lists have no common nodes. At this time, both pointers point to `null`, and we can return either one. + +The time complexity is $O(m+n)$, where $m$ and $n$ are the lengths of the linked lists $headA$ and $headB$ respectively. The space complexity is $O(1)$. @@ -61,11 +69,11 @@ class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: - cur1, cur2 = headA, headB - while cur1 != cur2: - cur1 = headB if cur1 is None else cur1.next - cur2 = headA if cur2 is None else cur2.next - return cur1 + a, b = headA, headB + while a != b: + a = a.next if a else headB + b = b.next if b else headA + return a ``` ```java @@ -82,12 +90,12 @@ class Solution: */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - ListNode cur1 = headA, cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 == null ? headB : cur1.next; - cur2 = cur2 == null ? headA : cur2.next; + ListNode a = headA, b = headB; + while (a != b) { + a = a == null ? headB : a.next; + b = b == null ? headA : b.next; } - return cur1; + return a; } } ``` @@ -104,13 +112,12 @@ public class Solution { class Solution { public: ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) { - ListNode* cur1 = headA; - ListNode* cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1->next : headB; - cur2 = cur2 ? cur2->next : headA; + ListNode *a = headA, *b = headB; + while (a != b) { + a = a ? a->next : headB; + b = b ? b->next : headA; } - return cur1; + return a; } }; ``` @@ -124,20 +131,44 @@ public: * } */ func getIntersectionNode(headA, headB *ListNode) *ListNode { - cur1, cur2 := headA, headB - for cur1 != cur2 { - if cur1 == nil { - cur1 = headB + a, b := headA, headB + for a != b { + if a == nil { + a = headB } else { - cur1 = cur1.Next + a = a.Next } - if cur2 == nil { - cur2 = headA + if b == nil { + b = headA } else { - cur2 = cur2.Next + b = b.Next } } - return cur1 + return a +} +``` + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null { + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; + } + return a; } ``` @@ -156,16 +187,42 @@ func getIntersectionNode(headA, headB *ListNode) *ListNode { * @return {ListNode} */ var getIntersectionNode = function (headA, headB) { - let cur1 = headA; - let cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1.next : headB; - cur2 = cur2 ? cur2.next : headA; + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; } - return cur1; + return a; }; ``` +```swift +/** + * Definition for singly-linked list. + * public class ListNode { + * public var val: Int + * public var next: ListNode? + * public init(_ val: Int) { + * self.val = val + * self.next = nil + * } + * } + */ + +class Solution { + func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? { + var a = headA + var b = headB + while a !== b { + a = a == nil ? headB : a?.next + b = b == nil ? headA : b?.next + } + return a + } +} +``` + diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.cpp b/lcci/02.07.Intersection of Two Linked Lists/Solution.cpp index 753db3cdd199c..6c4f6f2552d78 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/Solution.cpp +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.cpp @@ -9,12 +9,11 @@ class Solution { public: ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) { - ListNode* cur1 = headA; - ListNode* cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1->next : headB; - cur2 = cur2 ? cur2->next : headA; + ListNode *a = headA, *b = headB; + while (a != b) { + a = a ? a->next : headB; + b = b ? b->next : headA; } - return cur1; + return a; } }; \ No newline at end of file diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.go b/lcci/02.07.Intersection of Two Linked Lists/Solution.go index 217528bd00f5f..2cf2360642b64 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/Solution.go +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.go @@ -6,18 +6,18 @@ * } */ func getIntersectionNode(headA, headB *ListNode) *ListNode { - cur1, cur2 := headA, headB - for cur1 != cur2 { - if cur1 == nil { - cur1 = headB + a, b := headA, headB + for a != b { + if a == nil { + a = headB } else { - cur1 = cur1.Next + a = a.Next } - if cur2 == nil { - cur2 = headA + if b == nil { + b = headA } else { - cur2 = cur2.Next + b = b.Next } } - return cur1 + return a } \ No newline at end of file diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.java b/lcci/02.07.Intersection of Two Linked Lists/Solution.java index ee4bb36e17936..9662eaaf538f7 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/Solution.java +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.java @@ -11,11 +11,11 @@ */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - ListNode cur1 = headA, cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 == null ? headB : cur1.next; - cur2 = cur2 == null ? headA : cur2.next; + ListNode a = headA, b = headB; + while (a != b) { + a = a == null ? headB : a.next; + b = b == null ? headA : b.next; } - return cur1; + return a; } } \ No newline at end of file diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.js b/lcci/02.07.Intersection of Two Linked Lists/Solution.js index d1ca97e8900a6..934643598feee 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/Solution.js +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.js @@ -12,11 +12,11 @@ * @return {ListNode} */ var getIntersectionNode = function (headA, headB) { - let cur1 = headA; - let cur2 = headB; - while (cur1 != cur2) { - cur1 = cur1 ? cur1.next : headB; - cur2 = cur2 ? cur2.next : headA; + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; } - return cur1; + return a; }; diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.py b/lcci/02.07.Intersection of Two Linked Lists/Solution.py index 000c74aac0285..bedd686dd2534 100644 --- a/lcci/02.07.Intersection of Two Linked Lists/Solution.py +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.py @@ -7,8 +7,8 @@ class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: - cur1, cur2 = headA, headB - while cur1 != cur2: - cur1 = headB if cur1 is None else cur1.next - cur2 = headA if cur2 is None else cur2.next - return cur1 + a, b = headA, headB + while a != b: + a = a.next if a else headB + b = b.next if b else headA + return a diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.swift b/lcci/02.07.Intersection of Two Linked Lists/Solution.swift new file mode 100644 index 0000000000000..fa41e06ad2024 --- /dev/null +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.swift @@ -0,0 +1,23 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * public var val: Int + * public var next: ListNode? + * public init(_ val: Int) { + * self.val = val + * self.next = nil + * } + * } + */ + +class Solution { + func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? { + var a = headA + var b = headB + while a !== b { + a = a == nil ? headB : a?.next + b = b == nil ? headA : b?.next + } + return a + } +} diff --git a/lcci/02.07.Intersection of Two Linked Lists/Solution.ts b/lcci/02.07.Intersection of Two Linked Lists/Solution.ts new file mode 100644 index 0000000000000..d5321f905bf8c --- /dev/null +++ b/lcci/02.07.Intersection of Two Linked Lists/Solution.ts @@ -0,0 +1,21 @@ +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null { + let a = headA; + let b = headB; + while (a != b) { + a = a ? a.next : headB; + b = b ? b.next : headA; + } + return a; +} diff --git a/solution/0100-0199/0160.Intersection of Two Linked Lists/README.md b/solution/0100-0199/0160.Intersection of Two Linked Lists/README.md index 2110a951d5dfe..dba6890c4b61c 100644 --- a/solution/0100-0199/0160.Intersection of Two Linked Lists/README.md +++ b/solution/0100-0199/0160.Intersection of Two Linked Lists/README.md @@ -96,13 +96,13 @@ ### 方法一:双指针 -使用两个指针 $a$, $b$ 分别指向两个链表 $headA$, $headB$。 +我们使用两个指针 $a$, $b$ 分别指向两个链表 $headA$, $headB$。 同时遍历链表,当 $a$ 到达链表 $headA$ 的末尾时,重新定位到链表 $headB$ 的头节点;当 $b$ 到达链表 $headB$ 的末尾时,重新定位到链表 $headA$ 的头节点。 -若两指针相遇,所指向的结点就是第一个公共节点。若没相遇,说明两链表无公共节点,此时两个指针都指向 $null$。 +若两指针相遇,所指向的结点就是第一个公共节点。若没相遇,说明两链表无公共节点,此时两个指针都指向 `null`,返回其中一个即可。 -时间复杂度 $O(m+n)$,其中 $m$ 和 $n$ 分别是链表 $headA$ 和 $headB$ 的长度。 +时间复杂度 $O(m+n)$,其中 $m$ 和 $n$ 分别是链表 $headA$ 和 $headB$ 的长度。空间复杂度 $O(1)$。 diff --git a/solution/0100-0199/0160.Intersection of Two Linked Lists/README_EN.md b/solution/0100-0199/0160.Intersection of Two Linked Lists/README_EN.md index 47e607252ffd5..9c31b1e66ef26 100644 --- a/solution/0100-0199/0160.Intersection of Two Linked Lists/README_EN.md +++ b/solution/0100-0199/0160.Intersection of Two Linked Lists/README_EN.md @@ -76,7 +76,15 @@ Explanation: The two lists do not intersect, so return null. ## Solutions -### Solution 1 +### Solution 1: Two Pointers + +We use two pointers $a$ and $b$ to point to two linked lists $headA$ and $headB$ respectively. + +We traverse the linked lists simultaneously. When $a$ reaches the end of the linked list $headA$, it is repositioned to the head node of the linked list $headB$. When $b$ reaches the end of the linked list $headB$, it is repositioned to the head node of the linked list $headA$. + +If the two pointers meet, the node they point to is the first common node. If they don't meet, it means that the two linked lists have no common nodes. At this time, both pointers point to `null`, and we can return either one. + +The time complexity is $O(m+n)$, where $m$ and $n$ are the lengths of the linked lists $headA$ and $headB$ respectively. The space complexity is $O(1)$.