题目来源:K个一组反转链表
在bilibili上的视频讲解:https://www.bilibili.com/video/BV11w411V7Ar/
题目描述
给你链表的头节点 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
解题思路
思路步骤
step1:定义一个虚拟头节点empty和一个pre指针
- empty的next指向head头节点
- cur指向empty,cur表示反转好后链表的尾节点
step2:反转k个节点,与反转链表Ⅱ的思路一样的,但要注意的是:
- 需要判断传入的链表节点个数是否大于等于k,如果大于等于就进行反转操作,负责就直接返回链表
step3:将cur指针移动到反转好一组链表的尾节点(即向前移动k个节点)
step4:循环重复step2、step3,当cur为空时,说明遍历完了所有的节点,此时结束循环,返回empty.next
思路动画
代码
Python代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverse(self, head, k):
fast = head
slow = head
pre = None
q = head
n = k
while n and q:
q = q.next
n -= 1
if n > 0 and q == None:
return head
while k:
fast = fast.next
slow.next = pre
pre = slow
slow = fast
k -= 1
head.next = fast
return pre
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
empty = ListNode()
empty.next = head
cur = empty
while True:
cur.next = self.reverse(cur.next, k)
n = k
while n and cur:
cur = cur.next
n -= 1
if cur == None:
break
return empty.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* reverse(ListNode* head, int k) {
ListNode* fast = head;
ListNode* slow = head;
ListNode* pre = nullptr;
ListNode* q = head;
int n = k;
while (n && q) {
q = q->next;
n -= 1;
}
if (n > 0 && q == nullptr) {
return head;
}
while (k) {
fast = fast->next;
slow->next = pre;
pre = slow;
slow = fast;
k -= 1;
}
head->next = fast;
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* empty = new ListNode(0);
empty->next = head;
ListNode* cur = empty;
while (true) {
cur->next = reverse(cur->next, k);
int n = k;
while (n && cur) {
cur = cur->next;
n -= 1;
}
if (cur == nullptr) {
break;
}
}
ListNode* result = empty->next;
delete empty;
return result;
}
};
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 reverse(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
ListNode pre = null;
ListNode q = head;
int n = k;
while (n > 0 && q != null) {
q = q.next;
n -= 1;
}
if (n > 0 && q == null) {
return head;
}
while (k > 0) {
fast = fast.next;
slow.next = pre;
pre = slow;
slow = fast;
k -= 1;
}
head.next = fast;
return pre;
}
public ListNode reverseKGroup(ListNode head, int k) {
ListNode empty = new ListNode();
empty.next = head;
ListNode cur = empty;
while (true) {
cur.next = reverse(cur.next, k);
int n = k;
while (n > 0 && cur != null) {
cur = cur.next;
n -= 1;
}
if (cur == null) {
break;
}
}
return empty.next;
}
}