day16 leetcode-hot100-31(链表10)
25. K 个一组翻转链表 - 力扣(LeetCode)
1.模拟法
思路
将这个过程拆解为两个步骤,第一步将单分组的节点反转,第二步将反转后的链表加入原链表。
针对节点反转很容易,参考之前的206. 反转链表 - 力扣(LeetCode)
针对反转后的链表加入原链表,我们需要该链表前一个节点pre,以及后面一个节点nex。
所以我们要提前将pre与nex存储起来。
具体步骤
(1)创建哨兵节点dump,让头节点不再特殊。同时pre=dump为第一个需要反转链表的前一个节点。
(2)判断需要反转的链表是否有k个长度,若有则继续,若无直接输出结果dump.next;
(3)存储nex,pre,方便后续加入原链表。
(4)反转链表(返回新的头节点与尾节点),并将链表加入原链表。
(5)更新pre为tail,head为tail.next,方便下一次循环。
具体代码
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode dump = new ListNode(0,head);ListNode pre = dump;while(head!=null){ListNode tail = pre;for(int i=0;i<k;i++){tail=tail.next;if(tail==null){return dump.next;}}ListNode nex = tail.next;ListNode[] rev = myRev(head,tail);head = rev[0];tail = rev[1];pre.next = head;tail.next=nex;pre=tail;head = tail.next;}return dump.next;}public ListNode[] myRev(ListNode n1,ListNode n2){ListNode pre1 = n2.next;ListNode end = pre1;ListNode cur = n1;while(cur!=end){ListNode next1 =cur.next;cur.next=pre1;pre1=cur;cur=next1;}ListNode[] r = {n2,n1};return r;}
}