简单来说:就是给你一个链表,将其分组,第一组 有 1 个 节点,第二组有两个节点,第三组有三个节点,以此类推。直到剩余的节点,无法满足下一次分组,
我们要做的就是将 这些组中,节点个数是偶数的,进行反转。但不影响链表的链接。
目的: 记录交换 链表偶数长度组 头节点 的 前驱节点。用于反转后,接回链表。
前面的搞定了,后面还需要一个节点变量来记录 链表偶数长度组 尾结点 的 后驱节点,用于反转后,接回链表。
且 等于 head
但与往常有些不同
用的for循环,且循环条件就是 变量flag 必须为 0,也就是 tail 不能为 null,接着往后看就知道了。
为什么要这么写呢?因为 我们需要 下标来判断 进行分组 和判断该组是否为 偶数组,如果是那么就进行反转。
至于,为什么 i 初始值是1,是因为,我们都知道第一个分组,只有一个节点,肯定不是偶数组,
后面,我会利用节点个数 与 i 的关系,来让 prevHead 和 tail 进行移位,方便确定偶数组的头节点前驱 和 尾结点,
在分析之前该代码之前,该循环条件可以提前讲一下 tail != null 和 count < j 这两个条件中tail != null 是为了防止 后续 “分组” 时,剩余节点不够。
而 count < j 是用来分组的。后面分析的时候,你就知道哦了。
再来接着看,反转函数的实现。(注意我们reverseHead 是 偶数组的前一个节点)
注意 头节点的前驱节点 与 该组的尾结点,都是在 prevHead 和 tail 移动前,记录了当前组头节点的前驱节点 和 该组的尾结点。所以,放心将该两个值,交给 reverse 。
/** * 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 reverseEvenLengthGroups(ListNode head) {
ListNode prevHead = new ListNode();
prevHead.next = head;
ListNode tail = head;
int flag = 0;
for(int i = 1; flag == 0;i++){
ListNode reverseHead = prevHead;
ListNode reverseTail = null;
int count = 0;
while(tail!=null && count < i){
reverseTail = tail;
prevHead = prevHead.next;
tail =tail.next;
count++;
if(tail == null){// 链表节点已分配完
flag = 1;
}
}
if(count % 2 == 0){
prevHead = reverse(reverseHead,reverseTail);
}
}
return head;// 因为第一组是只有一节点,不用反转,也就是说 head 没有改变,直接返回就行了。
}
public ListNode reverse(ListNode prevHead,ListNode tail){
ListNode head = prevHead.next;
ListNode cur = head;
ListNode prev = tail.next;
while(prev != tail){
ListNode curNext = cur.next;
cur.next = prev;
prev = cur;
cur = curNext;
}
prevHead.next = tail;
return head;
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/DarkAndGrey/article/details/122313549
内容来源于网络,如有侵权,请联系作者删除!