LeetCode第二十五题(K 个一组翻转链表)

125 阅读1分钟

双指针法

核心思想: “框出”k个结点为一组进行单链表的局部翻转,不足k个结点,则保持原有顺序

/**
 * 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 resList = new ListNode(0, head);//结果链表的理论头结点
        ListNode start = resList;//一组的相邻前一个结点,用于头插法
        ListNode end = resList;//一组中的最后一个结点
        ListNode endTemp = start;//标记下一组的相邻前一个结点
        int count = 0;//计数器
        while(end != null){
            if(count == k){//“框出”k个结点为一组进行单链表的局部翻转
                endTemp = start.next;
                groupReverse(start, end);//单链表的局部翻转
            }
            else{
                end = end.next;
                count++;
                continue;
            }
            start = endTemp;//start指向下一组的相邻前一个结点,进行下一组迭代
            end = endTemp;//end指向下一组的相邻前一个结点,进行下一组迭代
            count = 0;//计数器复原,进行下一组迭代
        }
        return resList.next;
    }
    //利用头插法实现单链表翻转
    public void groupReverse(ListNode start, ListNode end){
        ListNode finish = end.next;//用于记录局部单链表的边界,“相当于null”
        ListNode cur = start.next;//当前待插入的结点
        start.next = finish;
        while(cur != finish){
            ListNode temp = cur.next;
            cur.next = start.next;
            start.next = cur;
            cur = temp;
        }
    }
}