题目来源
题目描述
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例
示例 1:
输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3 输出:[3,2,1,4,5]
提示
- 链表中的节点数目为
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
题目解析
本题主要考察数据结构。
首先,我们可以思考下,如何反转(单向)链表(PS. 只能基于原来的节点操作)
比如,有单向链表:1->2->3,我们可以按照下面步骤操作将其反转:
当我们知道如何反转链表,我们可以继续思考:反转“指定范围”的子链表
比如,有单向链表:1->2->3->4->5,我们想要反转 2->3->4 子链,可以按如下步骤操作:
本题需要每K个一组进行反转,我们可以为输入的链表添加一个虚拟头 dummy_head,比如示例1如下图所示,按照下面图示逻辑:
最后返回 dummy_head.next 即为题解。
C源码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
void reverseList(struct ListNode* head, struct ListNode* tail) {
struct ListNode* tailNext = tail->next;
struct ListNode* pre = NULL;
struct ListNode* cur = head;
while (cur != tailNext) {
struct ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
struct ListNode* dummy_head = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy_head->val = 0;
dummy_head->next = head;
struct ListNode* preHead = dummy_head;
while (1) {
// K个节点一组,组的头节点是head,组的尾节点是tail
struct ListNode* tail = head;
for (int i = 1; i < k && tail != NULL; i++) {
tail = tail->next;
}
// 若 tail 为空,则当前组节点数量不足K个
if (tail == NULL) {
break;
}
// 反转操作前
// preHead -> head -> .... -> tail -> nxtTail
struct ListNode* nxtTail = tail->next;
// 反转 head~tail 范围
reverseList(head, tail);
// 反转操作后
// preHead -> tail -> .... -> head -> nxtTail
preHead->next = tail;
head->next = nxtTail;
// 继续下一组反转
preHead = head;
head = nxtTail;
}
return dummy_head->next;
}
C++源码实现
/**
* 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* reverseKGroup(ListNode* head, int k) {
ListNode* dummy_head = new ListNode(0, head);
ListNode* preHead = dummy_head;
while (true) {
// K个节点一组,组的头节点是head,组的尾节点是tail
ListNode* tail = head;
for (int i = 1; i < k && tail != nullptr; i++) {
tail = tail->next;
}
// 若 tail 为空,则当前组节点数量不足K个
if (tail == nullptr) {
break;
}
// 反转操作前
// preHead -> head -> .... -> tail -> nxtTail
ListNode* nxtTail = tail->next;
// 反转 head~tail 范围
reverseList(head, tail);
// 反转操作后
// preHead -> tail -> .... -> head -> nxtTail
preHead->next = tail;
head->next = nxtTail;
// 继续下一组反转
preHead = head;
head = nxtTail;
}
return dummy_head->next;
}
void reverseList(ListNode* head, ListNode* tail) {
ListNode* tailNext = tail->next;
ListNode* pre = nullptr;
ListNode* cur = head;
while (cur != tailNext) {
ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
}
};
Java源码实现
/**
* 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 reverseKGroup(ListNode head, int k) {
ListNode dummy_head = new ListNode(0, head);
ListNode preHead = dummy_head;
while (true) {
// K个节点一组,组的头节点是head,组的尾节点是tail
ListNode tail = head;
for (int i = 1; i < k && tail != null; i++) {
tail = tail.next;
}
// 若 tail 为空,则当前组节点数量不足K个
if (tail == null) {
break;
}
// 反转操作前
// preHead -> head -> .... -> tail -> nxtTail
ListNode nxtTail = tail.next;
// 反转 head~tail 范围
reverseList(head, tail);
// 反转操作后
// preHead -> tail -> .... -> head -> nxtTail
preHead.next = tail;
head.next = nxtTail;
// 继续下一组反转
preHead = head;
head = nxtTail;
}
return dummy_head.next;
}
public void reverseList(ListNode head, ListNode tail) {
ListNode tailNext = tail.next;
ListNode pre = null;
ListNode cur = head;
while (cur != tailNext) {
ListNode nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
}
}
Python源码实现
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
def reverseList(head, tail):
tailNext = tail.next
pre = None
cur = head
while cur != tailNext:
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: Optional[ListNode]
:type k: int
:rtype: Optional[ListNode]
"""
dummy_head = ListNode(0, head)
preHead = dummy_head
while True:
# K个节点一组,组的头节点是head,组的尾节点是tail
tail = head
for i in range(1, k):
if tail:
tail = tail.next
else:
break
# 若 tail 为空,则当前组节点数量不足K个
if tail is None:
break
# 反转操作前
# preHead -> head -> .... -> tail -> nxtTail
nxtTail = tail.next
# 反转 head~tail 范围
reverseList(head, tail)
# 反转操作后
# preHead -> tail -> .... -> head -> nxtTail
preHead.next = tail
head.next = nxtTail
# 继续下一组反转
preHead = head
head = nxtTail
return dummy_head.next
JavaScript源码实现
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
var reverseList = function (head, tail) {
const tailNext = tail.next;
let pre = null;
let cur = head;
while (cur != tailNext) {
const nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
}
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function (head, k) {
const dummy_head = new ListNode(0, head);
let preHead = dummy_head;
while (true) {
// K个节点一组,组的头节点是head,组的尾节点是tail
let tail = head;
for (let i = 1; i < k && tail != null; i++) {
tail = tail.next;
}
// 若 tail 为空,则当前组节点数量不足K个
if (tail == null) {
break;
}
// 反转操作前
// preHead -> head -> .... -> tail -> nxtTail
const nxtTail = tail.next;
// 反转 head~tail 范围
reverseList(head, tail);
// 反转操作后
// preHead -> tail -> .... -> head -> nxtTail
preHead.next = tail;
head.next = nxtTail;
// 继续下一组反转
preHead = head;
head = nxtTail;
}
return dummy_head.next;
};