链表
题目描述
给定链表 head
和两个整数 m
和 n
. 遍历该链表并按照如下方式删除节点:
开始时以头节点作为当前节点.
保留以当前节点开始的前 m
个节点.
删除接下来的 n
个节点.
重复步骤 2 和 3, 直到到达链表结尾.
在删除了指定结点之后, 返回修改过后的链表的头节点.
示例 1:
输入: head = [1,2,3,4,5,6,7,8,9,10,11,12,13], m = 2, n = 3
输出: [1,2,6,7,11,12]
解析: 保留前(m = 2)个结点, 也就是以黑色节点表示的从链表头结点开始的结点(1 ->2).
删除接下来的(n = 3)个结点(3 -> 4 -> 5), 在图中以红色结点表示.
继续相同的操作, 直到链表的末尾.
返回删除结点之后的链表的头结点.
示例 2:
输入: head = [1,2,3,4,5,6,7,8,9,10,11], m = 1, n = 3
输出: [1,5,9]
解析: 返回删除结点之后的链表的头结点.
示例 3:
输入: head = [1,2,3,4,5,6,7,8,9,10,11], m = 3, n = 1
输出: [1,2,3,5,6,7,9,10,11]
示例 4:
输入: head = [9,3,7,7,9,10,8,2], m = 1, n = 2
输出: [9,7,8]
提示:
链表中节点数目在范围 [1, 104 ]
内
1 <= Node.val <= 106
1 <= m, n <= 1000
进阶: 你能通过 就地 修改链表的方式解决这个问题吗?
解法
方法一:模拟
我们可以模拟整个删除过程,首先用 $\textit{pre}$ 指针指向链表头部,然后遍历链表,移动 $m - 1$ 步,如果 $\textit{pre}$ 为空,说明从当前节点开始的节点个数小于 $m$,直接返回头部;否则,用 $\textit{cur}$ 指针指向 $\textit{pre}$,然后移动 $n$ 步,如果 $\textit{cur}$ 为空,说明从 $\textit{pre}$ 开始的节点个数小于 $m + n$,直接将 $\textit{pre}$ 的 $\textit{next}$ 指向 $\text{null}$;否则,将 $\textit{pre}$ 的 $\textit{next}$ 指向 $\textit{cur}$ 的 $\textit{next}$,然后将 $\textit{pre}$ 移动到 $\textit{pre}$ 的 $\textit{next}$。继续遍历链表,直到 $\textit{pre}$ 为空,返回头部。
时间复杂度 $O(n)$,其中 $n$ 是链表中节点的个数。空间复杂度 $O(1)$。
Python3 Java C++ Go TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 # Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution :
def deleteNodes ( self , head : ListNode , m : int , n : int ) -> ListNode :
pre = head
while pre :
for _ in range ( m - 1 ):
if pre :
pre = pre . next
if pre is None :
return head
cur = pre
for _ in range ( n ):
if cur :
cur = cur . next
pre . next = None if cur is None else cur . next
pre = pre . next
return head
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /**
* Definition for singly-linked list.
* 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; }
* }
*/
class Solution {
public ListNode deleteNodes ( ListNode head , int m , int n ) {
ListNode pre = head ;
while ( pre != null ) {
for ( int i = 0 ; i < m - 1 && pre != null ; ++ i ) {
pre = pre . next ;
}
if ( pre == null ) {
return head ;
}
ListNode cur = pre ;
for ( int i = 0 ; i < n && cur != null ; ++ i ) {
cur = cur . next ;
}
pre . next = cur == null ? null : cur . next ;
pre = pre . next ;
}
return head ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 /**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public :
ListNode * deleteNodes ( ListNode * head , int m , int n ) {
auto pre = head ;
while ( pre ) {
for ( int i = 0 ; i < m - 1 && pre ; ++ i ) {
pre = pre -> next ;
}
if ( ! pre ) {
return head ;
}
auto cur = pre ;
for ( int i = 0 ; i < n && cur ; ++ i ) {
cur = cur -> next ;
}
pre -> next = cur ? cur -> next : nullptr ;
pre = pre -> next ;
}
return head ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 /**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteNodes ( head * ListNode , m int , n int ) * ListNode {
pre := head
for pre != nil {
for i := 0 ; i < m - 1 && pre != nil ; i ++ {
pre = pre . Next
}
if pre == nil {
return head
}
cur := pre
for i := 0 ; i < n && cur != nil ; i ++ {
cur = cur . Next
}
pre . Next = nil
if cur != nil {
pre . Next = cur . Next
}
pre = pre . Next
}
return head
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /**
* 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 deleteNodes ( head : ListNode | null , m : number , n : number ) : ListNode | null {
let pre = head ;
while ( pre ) {
for ( let i = 0 ; i < m - 1 && pre ; ++ i ) {
pre = pre . next ;
}
if ( ! pre ) {
break ;
}
let cur = pre ;
for ( let i = 0 ; i < n && cur ; ++ i ) {
cur = cur . next ;
}
pre . next = cur ? . next || null ;
pre = pre . next ;
}
return head ;
}
GitHub