package com.example.demo.leecode;
import java.util.Stack;
/**
 * K 个一组翻转链表
 * @Date 2020/12/18
 * @author Tang
 *
 * 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
 * k 是一个正整数,它的值小于或等于链表的长度。
 * 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
 */
public class ReverseNodesInKGroup {
    public ListNode execute(ListNode head, int k){
        //不需要反转的情况
        if(head.next == null || k <= 1){
            return head;
        }
        ListNode first = new ListNode();
        first.next = head;
        //递归每k个进行一次反转,first节点不参与反转
        reverseK(k, first);
        return first.next;
    }
    /**
     * 利用栈
     * 对k个元素进行翻转
     * 递归去翻转下k个元素
     * @param k
     */
    private void reverseK(int k, ListNode node){
        if(node.next == null){
            return;
        }
        ListNode first = node;
        Stack<ListNode> stack = new Stack<>();
        for(int i = k; i > 0; i--){
            if(node.next == null){
                return;
            }
            stack.push(node.next);
            node = node.next;
        }
        ListNode end = stack.peek().next;
        for(int i = k; i > 0; i--){
            first.next = stack.pop();
            first = first.next;
        }
        first.next = end;
        reverseK(k,first);
    }
    public static void main(String[] args) {
        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(3);
        ListNode l4 = new ListNode(4);
        ListNode l7 = new ListNode(5);
        ListNode l8 = new ListNode(6);
        l1.next = l2; l2.next = l3; l3.next = l4;
        l4.next = l7; l7.next = l8;
        ListNode execute = new ReverseNodesInKGroup().execute(l1, 0);
        System.out.println(execute.val);
        while(execute.hasNext()){
            execute = execute.next;
            System.out.println(execute.val);
        }
    }
}
class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) {
        this.val = val;
    }
    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
    boolean hasNext(){
        return next != null;
    }
}