K 个一组翻转链表
这道算法题就是链表多个算法思想的结合,解决这一道leetcodehot100的链表题至少能做一半了
大概有一下几个点
1.链表定位
2.链表翻转
3.哨兵节点
4.链表合并
看看题目
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
但说是算法思想很多,但这些个的算法难度复杂度加起来不过是o1+o1,还是o1
真正的难点是在翻转合并之后,精准的定位到哨兵和前缀节点
这是一开始的p0,用于合并
以及pre,用于翻转
这是一个k个链表翻转后的p0(p0是指向1)与pre(pre就是2),这里区分一下
这里p0是不会动的,然后pre是一直pre=pre.next的
所以现在的pre在蓝色链表原的最后一个,也就是翻转后的第一个
此时蓝色已经翻转了,所以我们这里需要做两个事情
1.将蓝色与后面的连起来
2.使得后面的部分也和链表最开始的状态一样(pre和p0的位置)
ListNode temp= p0.next;//记录一下翻转后末尾的节点,因为要用来当下一段的p0
p0.next.next = cur; //将蓝色和后面的连起来
p0.next = pre;//将蓝色部分与前面的连起来,因为p0会指向前一段的末尾
p0 = temp;//使得p0指向后面的头节点
下面直接开始做题
class Solution {public ListNode reverseKGroup(ListNode head, int k) {// 找到节点的数量nint n = 0;for (ListNode cur = head; cur != null; cur = cur.next) {n++;}//初始化前缀指针,哨兵节点ListNode dummy = new ListNode(0, head);ListNode p0 = dummy;ListNode pre = null;ListNode cur = head;for (; n >= k; n -= k) {//翻转链表,翻转后的pre是当前k个的最后一个,cur是下面k个的第一个for (int i = 0; i < k; i++) { ListNode nxt = cur.next;cur.next = pre; pre = cur;cur = nxt;}ListNode temp= p0.next;//记录一下翻转后末尾的节点,因为要用来当下一段的p0p0.next.next = cur; //将蓝色和后面的连起来p0.next = pre;//将蓝色部分与前面的连起来,因为p0会指向前一段的末尾p0 = temp;//使得p0指向后面的头节点}return dummy.next;}
}