题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
相关话题: 链表 难度: 困难
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
- 你的算法只能使用常数的额外空间。
- 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路:
思路很简单,基本方法和反转链表 II一样。
主要是确定边界,因为有可能最后剩余的节点不足k
个。
- 定义两个指针
p
和q
,p
和q
开始都指向子区间的开头节点的前驱 - 先让
q
走k
步,如果走完k
步,q != null
则表示够k
个,否则不够,直接结束 - 反转完一个子区间的节点,更新
p
和q
的指向
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0);
dummy.next = head;
head = dummy;
ListNode p = head, q = p;
ListNode cur = null;
while(q != null){
//让q先跑k步,判断区间内节点是否够k个
for(int i = 0;i < k && q != null;i++){
q = q.next;
}
//不够k个,直接跳出
if(q == null) break;
//否则反转子区间内的节点
cur = p.next;
for(int i = 1;i < k;i++){
ListNode x = cur.next;
cur.next = x.next;
x.next = p.next;
p.next = x;
}
//开始下一个区间
p = cur;
q = p;
}
return head.next;
}
}