1 题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2 代码实现
Java版本:
思路:
先对 k 个元素进行翻转;得到翻转后的 head, tail; 然后,第二翻转也有 head, tail ; 第一次的tail指向第二次的head。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int checkK(ListNode head, int k){
int count = 0;
while(head != null){
count += 1;
head = head.next;
}
return count;
}
public static ListNode reverse(ListNode head,int k) {
if (head == null) return head;
if (k == 1) return head;
ListNode pre = head;
ListNode cur = head.next;
pre.next = null;
ListNode tmp = null;
while(k>1) {
tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
k -= 1;
}
// 这里是关键,把第一次的翻转后的tail(即原来的head)指向下一次的未翻转前的head。
head.next = cur;
return pre;
}
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null) return head;
if(head.next == null){
return head;
}
ListNode newHead = new ListNode(0);
ListNode tail = new ListNode(0);
ListNode lastTail = new ListNode(0);
boolean first = true;
int N = checkK(head,k);
while(N>=k){
tail = head;
head = reverse(head,k);
if(first){
lastTail = tail;
newHead = head;
first = false;
}
else{
// 上一次的 tail 指向该次翻转后的head。
lastTail.next = head;
lastTail = tail;
}
head = tail.next;
N -= k;
}
return newHead;
}
}
python版本:
如果知道 k 个一组的链表翻转结果 head,tail,就容易完成递归;tail.next 为下一组k个链表的表头。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def helper(self, head, N, k):
if (N < k) or (head == None):
return head,None
dummy = ListNode(-1)
dummy.next = head
for _ in range(k-1):
next = head.next
head.next = next.next
next.next = dummy.next
dummy.next = next
tail = head
head = dummy.next
_head, _tail = self.helper(tail.next, N-k, k)
tail.next = _head
return head,tail
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
cnt = 0
t = head
while t != None:
cnt += 1
t = t.next
h, t = self.helper(head, cnt, k)
return h
两种方法思路都一样,只是在实现 k 个一组链表翻转的迭代实现不太同,python版本的迭代公式更简洁。