算法
算法 - k个一组翻转链表leetcode题目来源 代码实现参考
题目描述: 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。示例:
给你这个链表:1->2->3->4->5当 k = 2 时,应当返回: 2->1->4->3->5当 k = 3 时,应当返回: 3->2->1->4->5 算法思路:区间翻转 思路:每次反转将链表分成三部分,翻转中间链表再拼接 头 - 前驱 | 开始 - 结束 | 后继 - NULL特殊点:要求当不足k个时需要保留原值—>不足k个可以放弃翻转,直接退出 判定策略:每次向后遍历k个结点,确定一个结束位置 若结束位置为null,则剩余不足k个若结束点不为null,则至少满足k个 代码中参数理解:原链表:1 - 2 - 3 - 4 - 5 - null
要求:每个数字表示一个节点,若2个结点一反转
首先创建一个节点O作为前驱: O - 1 - 2 - 3 - 4 - 5 - null
第一次反转前两个节点:1,2,遍历后参数指向情况 pre -> O --------- 反转区间的前一个 start -> 1 --------- 反转区间的开始 end -> 2 --------- 反转区间的结束 next -> 3 --------- 反转区间的后继 反转区间为:[start, end],反转后的结果是:2 -> 1,返回的节点是2
通过拼接链表实现反转后链表和原链表的连接 start -> 1,此时就是反转链表尾部,故:start.next = next; 结果:2 - 1 - 3 - 4 - 5 - null pre -> O,此时就是反转链表的前驱,故:pre.next = 2 结果:O - 2 - 1 - 3 - 4 - 5 - null
具体边界值判定建议参考代码
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head == null) return null;ListNode top = new ListNode(0);top.next = head;//设定操作的基础变量ListNode pre = top;//反转区间前驱ListNode end = top;//反转区间结尾ListNode start = null;//反转区间开始ListNode next = null;//反转区间的后继int count = 0;//向后遍历的节点个数while (end.next != null){count = k;while (count-- > 0 && end != null)end = end.next;if (end == null)break;start = pre.next;next = end.next;end.next = null;//设置翻转区间的结束位置pre.next = reserve(start);//将翻转链表的头连接到翻转区间的前一个位置start.next = next;//翻转后的链表尾部连接到链表为下一个pre = start;//新的翻转区间的前驱就是上次翻转的结束end = pre;//重置新的起始位置}return top.next;}/**翻转算法,思路简单,当curr为null,则已经反转到了链表结尾*/public ListNode reserve(ListNode head){ListNode pre = null;ListNode curr = head;ListNode next = null;while (curr != null){next = curr.next;curr.next = pre;pre = curr;curr = next;}return pre;}}算法