BM3.[链表中的节点每k个一组翻转]

https://www.nowcoder.com/exam/oj?tab=%E7%AE%97%E6%B3%95%E7%AF%87&topicId=295
BM3.链表中的节点每k个一组翻转
题目分析
刚才我们已经完全掌握了如何翻转指定区间的链表,现在每K个节点进行翻转,那么是不是可用上我们上面已经写好的函数呢,每K个一组翻转转化为数学的通用公式也就是翻转[(n-1)*k+1, n*k],n代表了是第几组,那么一共能有几组需要求出整个链表的长度。
这道题目其实是一道hard的题目,但是分拆之后,非常的容易就做出来。
分解步骤
复用链表内指定区间翻转
public ListNode reverseBetween (ListNode head, int m, int n) {
ListNode dummy = new ListNode(-1);
int len = n - m;
dummy.next = head;
ListNode frontTmp = dummy;
while(--m > 0){
frontTmp = frontTmp.next;
}
ListNode pre = frontTmp.next;
ListNode lastTmp = pre;
ListNode cur = pre.next;
while(len-- > 0){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
frontTmp.next = pre;
lastTmp.next = cur;
return dummy.next;
}
求链表长度count
public ListNode reverseKGroup (ListNode head, int k) {
ListNode tail = head;
int count = 0;
while(tail != null){
tail = tail.next;
count++;
}
//分组翻转
return head;
}
计算有多少分组n,遍历分组n,翻转指定区间(n-1)*k+1, n*k,其次注意边界条件可以到达第n组
int n = count / k;
for(int i = 1; i <= n; i++){
head = reverseBetween(head, (i-1) * k + 1, i * k);
}
完整题解
import java.util.*;
public class Solution {
public ListNode reverseKGroup (ListNode head, int k) {
ListNode tail = head;
int count = 0;
while(tail != null){
tail = tail.next;
count++;
}
int n = count / k;
for(int i = 1; i <= n; i++){
//这里面的i代表的是第几个组所以不能
head = reverseBetween(head, (i-1) * k + 1, i * k);
}
return head;
}
//翻转指定区间的链表
public ListNode reverseBetween (ListNode head, int m, int n) {
ListNode dummy = new ListNode(-1);
int len = n - m;
dummy.next = head;
ListNode frontTmp = dummy;
while(--m > 0){
frontTmp = frontTmp.next;
}
ListNode pre = frontTmp.next;
ListNode lastTmp = pre;
ListNode cur = pre.next;
while(len-- > 0){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
frontTmp.next = pre;
lastTmp.next = cur;
return dummy.next;
}
}
复杂度分析:
- 时间复杂度:
-
,n为链表长度,最好翻转一次k=n,最坏1个就翻转n(n+1)/2 + n
- 空间复杂度:
,没有使用新的额外空间


查看23道真题和解析
