题目描述(题目链接)
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:你可以设计一个只使用常数额外空间的算法来解决此问题吗?你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例:
输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5]
输入:head = [1,2,3,4,5], k = 3 输出:[3,2,1,4,5]
求解思路
在反转链表的基础上,做n/k次翻转,再把他们连起来
代码
执行用时:1 ms, 在所有 Java 提交中击败了35.21%的用户
内存消耗:38.7 MB, 在所有 Java 提交中击败了48.82%的用户
/**
* 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) {
int n=0;
ListNode tmp = head;
while(tmp!=null){ //计算链表长度
n++;
tmp = tmp.next;
}
if(n==0) return null; //特殊情况处理
if(n<k) return head; //特殊情况处理
ListNode cur = head; //当前指针
ListNode pre = null; //前一个指针
ListNode before = null; //第一个指针(最后返回的指针)
for(int j=0;j<n/k;j++){
while(pre!=null&&pre.next!=null){
pre = pre.next; //pre指向每次要反转的节点的前一个节点
}
ListNode tail = null;
if(pre!=null){
tail = pre; //用tail指向每次要反转的节点的前一个节点
pre = pre.next;
}
for(int i=0;i<k;i++){ //反转链表(k个一组)
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
if(tail!=null){
tail.next = pre; //将上次翻转后的尾指向这次反转后的头
}
if(j==0){
before = pre; //第一次反转得到的头就是总的头
}
}
while(pre.next!=null){ //把后面不构成k个的连上
pre = pre.next;
}
pre.next = cur;
return before;
}
}