题目:
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
看到这道题,我们的思路是:
1.每k个节点一组进行翻转,那就把整个链表分为num /= k个;
2.k个一组翻转,最后一组存在不够k个的情况,就按原来的排起来;
3.当这些分组都排好之后进行组装,形成一条长链。
代码如下:
/**
* 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) {
if(head == null || head.next == null || k == 1){
return head;
}
ListNode p = head;
int num = 0;
while(p != null && num < k){
p = p.next;
num++;
} num /= k; //分组
if(num == 0){
return head;
}
ListNode curr = head;
ListNode tail = curr;
for(int i = 0;i < num;i++){ //每一组进行翻转
ListNode newNode = null;
ListNode newhead = curr;
int count = k;
while(count > 0){
p = curr;
curr = curr.next;
p.next = newNode;
newNode = p;
count--;
}
if(i == 0){
head = newNode;
}else{
tail.next = newNode;
tail = newhead;
}
}
while(curr != null){ //最后的尾
tail.next = curr;
tail = tail.next;
curr = curr.next;
}
return head;
}
}
但是,循环着做着同样的事,我们可以用一种方法来实现,是什么呢?当然是递归!
代码如下:
/**
* 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) {
if(head == null || head.next == null){
return head;
}
int count = 0;
ListNode curr = head;
while(count != k && curr != null){
curr = curr.next;
count++;
}
if(count == k){
curr = reverseKGroup(curr,k); //上一次翻转后的头节点
while(count -- > 0){ //翻转
ListNode tmp = head.next;
head.next = curr;
curr = head;
head = tmp;
}
head = curr;
}
return head;
}
}