k个一组反转链表(两两一组的进阶版)

1. 问题描述

给出一个链表,每 个节点一组进行翻转,并返回翻转后的链表。

是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

示例 :

给定这个链表:1->2->3->4->5

当 = 2 时,应当返回: 2->1->4->3->5

当 = 3 时,应当返回: 3->2->1->4->5

说明 :

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

2. 代码实现 

先判断能否翻转;若剩余结点数多于k,再局部翻转;最后注意局部间的连接。

/**
 * 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) {
        ListNode newhead = new ListNode(0);
        newhead.next = head;
        ListNode temphead = head;  //当前处理的局部链表翻转前的头结点
        ListNode pre = newhead;    //指向前一个局部链表中 翻转前的第一个结点(翻转后的最后一个结点)
        
        while(temphead != null) {
            int n = k;
            ListNode last = temphead;
            //判断能否翻转
            while(n > 0 && last != null) {
                last = last.next;
                n--;
            }
            if(n == 0) {
                n = k;
                ListNode p1 = last;
                ListNode p2 = temphead;
                ListNode p3 = p2;

                //实现局部翻转
                while(n > 0) {
                    p3 = p2.next;
                    p2.next = p1;
                    p1 = p2;
                    p2 = p3;
                    n--;
                }
                pre.next = p1;    //连接上一个局部链表
                pre = temphead;
            }
            temphead = last;
        }
     return newhead.next;
    }
}

猜你喜欢

转载自blog.csdn.net/wula_heixiu/article/details/86674827