Skip to content

feat: add solutions to lcci problem: No.02.03 #2307

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
Feb 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
10 changes: 5 additions & 5 deletions lcci/02.03.Delete Middle Node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@

## 解法

### 方法一
### 方法一:节点赋值

我们可以将当前节点的值替换为下一个节点的值,然后删除下一个节点。这样就可以达到删除当前节点的目的。

时间复杂度 $O(1)$,空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -39,10 +43,6 @@

class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
```
Expand Down
10 changes: 5 additions & 5 deletions lcci/02.03.Delete Middle Node/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

## Solutions

### Solution 1
### Solution 1: Node Assignment

We can replace the value of the current node with the value of the next node, and then delete the next node. This way, we can achieve the purpose of deleting the current node.

The time complexity is $O(1)$, and the space complexity is $O(1)$.

<!-- tabs:start -->

Expand All @@ -34,10 +38,6 @@

class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
```
Expand Down
4 changes: 0 additions & 4 deletions lcci/02.03.Delete Middle Node/Solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,5 @@

class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
142 changes: 83 additions & 59 deletions lcci/02.04.Partition List/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,17 @@

### 方法一:拼接链表

创建两个链表,一个存放小于 `x` 的节点,另一个存放大于等于 `x` 的节点,之后进行拼接即可。
我们创建两个链表 $left$ 和 $right$,分别用于存储小于 $x$ 的节点和大于等于 $x$ 的节点。

然后我们用两个指针 $p1$ 和 $p2$ 分别指向 $left$ 和 $right$ 的最后一个节点,初始时 $p1$ 和 $p2$ 都指向一个虚拟头节点。

接下来我们遍历链表 $head$,如果当前节点的值小于 $x$,我们就将当前节点添加到 $left$ 链表的末尾,即 $p1.next = head$,然后令 $p1 = p1.next$;否则我们就将当前节点添加到 $right$ 链表的末尾,即 $p2.next = head$,然后令 $p2 = p2.next$。

遍历结束后,我们将 $left$ 链表的尾节点指向 $right$ 链表的第一个有效节点,即 $p1.next = right.next$,然后将 $right$ 链表的尾节点指向空节点,即 $p2.next = null$。

最后我们返回 $left$ 链表的第一个有效节点。

时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -56,19 +66,19 @@

class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
l1, l2 = ListNode(0), ListNode(0)
cur1, cur2 = l1, l2
left, right = ListNode(0), ListNode(0)
p1, p2 = left, right
while head:
if head.val < x:
cur1.next = head
cur1 = cur1.next
p1.next = head
p1 = p1.next
else:
cur2.next = head
cur2 = cur2.next
p2.next = head
p2 = p2.next
head = head.next
cur1.next = l2.next
cur2.next = None
return l1.next
p1.next = right.next
p2.next = None
return left.next
```

```java
Expand All @@ -77,29 +87,27 @@ class Solution:
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode l1 = new ListNode(0);
ListNode l2 = new ListNode(0);
ListNode cur1 = l1, cur2 = l2;
while (head != null) {
ListNode left = new ListNode(0);
ListNode right = new ListNode(0);
ListNode p1 = left;
ListNode p2 = right;
for (; head != null; head = head.next) {
if (head.val < x) {
cur1.next = head;
cur1 = cur1.next;
p1.next = head;
p1 = p1.next;
} else {
cur2.next = head;
cur2 = cur2.next;
p2.next = head;
p2 = p2.next;
}
head = head.next;
}
cur1.next = l2.next;
cur2.next = null;
return l1.next;
p1.next = right.next;
p2.next = null;
return left.next;
}
}
```
Expand All @@ -110,35 +118,58 @@ class Solution {
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* l1 = new ListNode();
ListNode* l2 = new ListNode();
ListNode* cur1 = l1;
ListNode* cur2 = l2;
while (head != nullptr) {
ListNode* left = new ListNode(0);
ListNode* right = new ListNode(0);
ListNode* p1 = left;
ListNode* p2 = right;
for (; head; head = head->next) {
if (head->val < x) {
cur1->next = head;
cur1 = cur1->next;
p1->next = head;
p1 = p1->next;
} else {
cur2->next = head;
cur2 = cur2->next;
p2->next = head;
p2 = p2->next;
}
head = head->next;
}
cur1->next = l2->next;
cur2->next = nullptr;
return l1->next;
p1->next = right->next;
p2->next = nullptr;
return left->next;
}
};
```

```go
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func partition(head *ListNode, x int) *ListNode {
left, right := &ListNode{}, &ListNode{}
p1, p2 := left, right
for ; head != nil; head = head.Next {
if head.Val < x {
p1.Next = head
p1 = p1.Next
} else {
p2.Next = head
p2 = p2.Next
}
}
p1.Next = right.Next
p2.Next = nil
return left.Next
}
```

```ts
/**
* Definition for singly-linked list.
Expand All @@ -153,30 +184,23 @@ public:
*/

function partition(head: ListNode | null, x: number): ListNode | null {
if (head == null) {
return head;
}
let cur = head;
while (cur.next != null) {
let node = cur.next;
if (node.val < x) {
[head, node.next, cur.next] = [node, head, node.next];
const [left, right] = [new ListNode(), new ListNode()];
let [p1, p2] = [left, right];
for (; head; head = head.next) {
if (head.val < x) {
p1.next = head;
p1 = p1.next;
} else {
cur = cur.next;
p2.next = head;
p2 = p2.next;
}
}
return head;
p1.next = right.next;
p2.next = null;
return left.next;
}
```

<!-- tabs:end -->

### 方法二:头插法

题中指出,**不需要保留节点的相对位置**。

1. 遍历链表。
2. 当节点符合小于 `x` 条件时,将其移动至头节点前方,成为新的头节点。
3. 忽略大于等于 `x` 的节点。

<!-- end -->
Loading