题目描述:
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:
1->2->3->4->5
当 k = 2 时,应当返回:
2->1->4->3->5
当 k = 3 时,应当返回:
3->2->1->4->5
当看到这道题目的时候,我们应该首先想到把链表进行分组来逐个翻转。
这个时候就需要用到递归,把大的问题化为小问题,采用“分治”的思想。
但是在写代码之前,我们应该考虑到以下几点:
1.如果链表是空链表,直接返回null;
2.如果链表的长度小于 K ,直接返回该链表;
3.需要三个节点,prev,node,next,一个指向当前节点的前一个,一个是当前节点,一个指向当前节点的后一个;
4.需要一个 last 节点记录上一组翻转的节点翻转之前的最后一个节点。
上代码:
/**
* 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){
return null;
}
int size = 0;
//计算链表的长度
for(ListNode tmp = head; tmp != null; tmp = tmp.next){
size++;
}
//如果长度小于k,直接返回,不需要进行翻转
if(size < k){
return head;
}
ListNode node = head;
int pos = k;
ListNode newHead = null;
ListNode prev = null;
ListNode next = null;
while(pos >= 1){
next = node.next;
pos--;
if(pos == 0){
//要翻转的这一组中节点的最后一个
newHead = node;
}
node.next = prev;
prev = node;
node = next;
}
ListNode last = newHead; //记录上一组翻转的最后一个节点
while(last.next != null){
last = last.next;
}
ListNode nextHead = reverseKGroup(next, k);
last.next = nextHead;
return newHead;
}
}