算法 - k个一组翻转链表

算法 - 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;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值