链表中的节点K个一组翻转
1. 题目链接
https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e
2. 题目要求
题目描述
将给出的链表中的节点每 k
个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k
的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度 O(1)
例如:
给定的链表是 1→2→3→4→5
对于 k=2
, 你应该返回 2→1→4→3→5
对于 k=3
, 你应该返回 3→2→1→4→5
示例1
输入:{1,2,3,4,5},2
返回值:{2,1,4,3,5}
本题涉及的
ListNode
结构
class ListNode{
int val;
ListNode next;
ListNode(int x){
this.val = x;
next = null;
}
}
3. 代码思路
-
采用头插法解决。使用两个循环,K个结点为一组,外层循环用于定位到第某组,内层循环挨个遍历头插来翻转当前组。
-
用示例1中的例子举例,阐述步骤。
-
创建
表头结点preHead.next = head
, 为了使第一组结点的翻转操作和后边组的操作一致。创建pre = preHead
指针用于在其后头插结点。创建cur = head
指针用于头插之后连接后续结点;创建temp
结点用于遍历当前组节点,挨个头插。ListNode preHead = new ListNode(-1); ListNode pre = preHead; ListNode cur = head; ListNode temp = null;
-
使用
head
指针遍历链表,记录结点数量,用于后续分组遍历。int length = 0; // 记录结点数量 // 使用head指针遍历链表 while(head!=null){ ++length; head = head.next; }
-
对第一组结点使用头插法翻转。
temp = cur.next; cur.next = temp.next; temp.next = pre.next; pre.next = temp;
-
第一组翻转完毕之后,将
pre
指向cur
,即指向第一组的最后一个结点,第二组的前一个结点。cur
往后指一个结点,即第二组的第一个结点。pre = cur; cur = cur.next;
-
结果返回
preHead.next
即为每k个一组翻转之后的结果。
4. 代码实现
public class Solution { public ListNode reverseKGroup (ListNode head, int k) { if(head == null || head.next == null || k < 2) return head; ListNode preHead = new ListNode(-1); preHead.next = head; ListNode pre = preHead; ListNode cur = head; ListNode temp = null; int lenth = 0; while(head != null){ ++lenth; head = head.next; } for(int i = 0; i < lenth / k; i++){ for(int j = 1; j < k; j++){ temp = cur.next; cur.next = temp.next; temp.next = pre.next; pre.next = temp; } pre = cur; cur = cur.next; } return preHead.next; } }
-