问题描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度 O(1)
例如:
给定的链表是1→2→3→4→5
对于 k=2, 你应该返回 2→1→4→3→5
对于 k=3, 你应该返回 3→2→1→4→5
输入描述:
输入一个链表和指定的k值
输出描述:
翻转后的链表
示例
示例1
输入
1→2→3→4→5,2
输出
2→1→4→3→5
解决思路
分析
- 通过计算长度可以知道需要交换几轮,每一轮采用头插法的思路依次交换节点。
方法
- 通过计算长度以及采用头插法的方式实现翻转
代码实现
// 思路1
public class Solution {
/**
* 头插法交换节点
* 这里需要分别记录几个变量:
* 1、当前节点
* 2、交换节点
* 3、前置节点
*
* 事例1:(首次发生节点交换)
* pre -> 1(a) -> 2(b) -> post
* tmp = cur.next; 记录b节点 b = 2 -> post
* cur.next = tmp.next; a节点指向b节点的next a -> post
* tmp.next = pre.next; b节点指向头节点next节点 b -> a -> post
* pre.next = tmp; 头节点的next节点指向b节点 pre -> b -> a -> post
*
* 事例2:(第二次发生节点交换)
* pre -> 2 -> 1(a) -> 3(b) -> post
* tmp = cur.next; 记录b节点 b = 3 -> post
* cur.next = tmp.next; a节点指向b节点的next a -> post
* tmp.next = pre.next; b节点指向头节点next节点 b -> 2 -> a -> post
* pre.next = tmp; 头节点的next节点指向b节点 pre -> b -> 2 -> a -> post
*
*/
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || head.next == null || k < 2) {
return head;
}
//构造一个新的头节点,方便返回值时找到反转后链表的头节点。
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy, cur = head, tmp = null;
int len = 0;
while (head != null) {
++len;
head = head.next;
}
// 这里也是采用头插法的方式
for (int i = 0; i < len / k; i++) {
for (int j = 1; j < k; j++) {
tmp = cur.next; // 记录b节点
cur.next = tmp.next; // a节点指向b节点的next节点
tmp.next = pre.next; // b节点指定头节点的next节点
pre.next = tmp; // 头节点的next节点指向b节点
}
pre = cur;
cur = cur.next;
}
return dummy.next;
}
}
小伙伴如果想测试的话,可以直接到牛客网这个链接做测试