25. K 个一组翻转链表 + 链表的翻转

25. K 个一组翻转链表

25. K 个一组翻转链表

题目描述

题解分析

  1. 这题的主要解决思路就是链表的翻转,关键是要找到每次翻转的头结点和尾结点。
  2. 外层是一个while(true)循环,内存找到本次需要翻转的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 dumyHead = new ListNode(0);//创建虚拟头结点
        dumyHead.next = head;
        ListNode pre = dumyHead;
        while(head != null){
            ListNode temp = pre;
            for(int i=0; i<k; i++){//判断剩下的链表是否够k个结点
                temp = temp.next;
                if(temp == null)
                    return dumyHead.next;//直接返回链表
            }
            ListNode next = temp.next;
            ListNode[] res = reverseLink(head, temp);
            head = res[0];//头结点
            temp = res[1];//尾结点
            pre.next = head;
            temp.next = next;
            pre = temp;
            head = temp.next;//新的头结点
        }
        return dumyHead.next;
    }
    /*
    翻转头结点和尾结点之间的这段链表
    */
    public ListNode[] reverseLink(ListNode head, ListNode tail){
        ListNode pre = tail.next;//这里很关键,前置结点设置为尾结点的下一个结点
        ListNode current = head;
        while(pre != tail){//注意这里是pre不等于尾结点
            ListNode temp = current.next;
            current.next = pre;
            pre = current;
            current = temp;
        }
        return new ListNode[]{tail, head};
    }
}

解法二:递归法

  1. 反转链表题目类似,本题也可以使用递归法来实现,只不过实现的步骤稍微有些麻烦。
  2. 递归方法中,每次返回的是子递归的新头节点newHead,在递归之后,需要将当前头节点head的next指针指向子递归的头节点。
  3. 需要注意的是,在递归边界中,如果遇到了head为null或者head.next为null,都需要返回head表示无法翻转空节点或者单个节点。
/**
 * 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) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode tail = head;
        for(int i=0; i<k-1; i++){
            tail = tail.next;
            if(tail == null){
                return head;
            }
        }
        ListNode[] temp = reverse(head, tail);
        ListNode newHead = temp[0];
        head.next = reverseKGroup(temp[1].next, k);
        return newHead;
    }

    private ListNode[] reverse(ListNode slow, ListNode fast){
        ListNode pre = fast.next;
        ListNode now = slow;
        while(pre != fast){
            ListNode temp = now.next;
            now.next = pre;
            pre = now;
            now = temp;
        }
        return new ListNode[]{fast, slow};
    }
}
posted @ 2021-03-20 18:37  Garrett_Wale  阅读(34)  评论(0编辑  收藏  举报