Skip to content

feat: add solutions to lcci problem: No.02.07 #2529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 89 additions & 32 deletions lcci/02.07.Intersection of Two Linked Lists/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@

## 解法

### 方法一
### 方法一:双指针

我们使用两个指针 $a$, $b$ 分别指向两个链表 $headA$, $headB$。

同时遍历链表,当 $a$ 到达链表 $headA$ 的末尾时,重新定位到链表 $headB$ 的头节点;当 $b$ 到达链表 $headB$ 的末尾时,重新定位到链表 $headA$ 的头节点。

若两指针相遇,所指向的结点就是第一个公共节点。若没相遇,说明两链表无公共节点,此时两个指针都指向 `null`,返回其中一个即可。

时间复杂度 $O(m+n)$,其中 $m$ 和 $n$ 分别是链表 $headA$ 和 $headB$ 的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -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
Expand All @@ -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;
}
}
```
Expand All @@ -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;
}
};
```
Expand All @@ -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;
}
```

Expand All @@ -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
}
}
```

<!-- tabs:end -->

<!-- end -->
121 changes: 89 additions & 32 deletions lcci/02.07.Intersection of Two Linked Lists/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)$.

<!-- tabs:start -->

Expand All @@ -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
Expand All @@ -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;
}
}
```
Expand All @@ -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;
}
};
```
Expand All @@ -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;
}
```

Expand All @@ -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
}
}
```

<!-- tabs:end -->

<!-- end -->
11 changes: 5 additions & 6 deletions lcci/02.07.Intersection of Two Linked Lists/Solution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};
18 changes: 9 additions & 9 deletions lcci/02.07.Intersection of Two Linked Lists/Solution.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading