这个困难题目并不困难,主要是考察逻辑能力
解题思路
这个题看着是困难的题目,实际上是考察逻辑的。
并不需要太过复杂的算法,只要搞清楚组和组之间的关系就好了。
写出来20、30分钟,debug用了两个小时。
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public static ListNode reverseKGroup(ListNode head, int k) {
//谁人不知悔改你却把我来相爱
ListNode temp = head;
int sum = 0;
while (temp != null) {
sum++;
temp = temp.next;
}
final int group = sum / k; //查看共分为多少组
temp = head; //用temp进行遍历
ListNode savePrevious = null; //保存前一个listnode
ListNode saveMid = null; //保存中间的listnode
ListNode saveNext = null; //保存中间下一个listnode
ListNode groupHead = null; //保存每一个组排翻转后的头节点
ListNode groupTail = null; //保存每一个组翻转后的尾节点
//ListNode preGroupHead=null; //保存每一个前一个组翻转后的头节点
ListNode preGroupTail = null; //保存每一个前一个组翻转后的尾节点
ListNode rehead = null; //保存整个数组翻转后的头节点
if (sum < 2 || k < 2) { //如果sum<2或k<2的话,直接返回原来的链表
return head;
}
for (int i = 0; i < group; i++) { //有多少组就进行多少组操作。
for (int j = 0; j < k - 1; j++) { //对每一个组进行遍历
if (j == 0) { //如果j==0的话
groupTail = temp; //当前组尾部
savePrevious = temp; //上一个节点
temp = temp.next;
saveMid = temp;
temp=temp.next;
saveNext = temp;
saveMid.next = savePrevious;
} else {
savePrevious = saveMid;
saveMid = saveNext;
temp = temp.next;
saveNext = temp;
saveMid.next = savePrevious;
}
if (j == k - 2) { //单独处理,防止k=2的情况发生
groupHead = saveMid;
if (i == 0) {
rehead = groupHead;
}
if (preGroupTail != null) {
preGroupTail.next = groupHead;
}
preGroupTail = groupTail;
}
}
}
if (k * group <sum ) { //处理后续节点
preGroupTail.next = temp;
}else{
preGroupTail.next=null;
}
return rehead;
}
}