1、递归:时间复杂度O(n),空间复杂度O(n/k)递归的深度 
思路:双指针每一段进行反转,递归返回的每一次进行拼接
public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        //双指针,pre代表需要反转的起始点,node用来寻找下一段反转的起始点
        ListNode node = head;
        ListNode pre = head;
        int m = 0;
        //将node定位在下一段起始点的前一位置上
        //比如K是2,数据是1,2,3,4,5;那么node定位在2上
        //因为需要断开2与3的连接
        while(m<k-1&&node!=null){
           node = node.next;
           m++; 
        }
        //如果跳出循环,node是null,那么证明长度不满足K个了,直接返回起始点
        if(node==null){
            return pre;
        }
        else{
            //断开前一段和后一段的连接
            ListNode temp = node.next;
            node.next=null;
            node = temp;
            //将当前段进行反转:1,2反转成为->2,1
            ListNode reverseNode = reverse(pre);
            //递归找下一段
            ListNode list = reverseKGroup(node,k);
            //假设这一层是1,2->反转成2->1
            //1就是最开始的起始点pre
            //2是反转得到的reverseNode;
            //所以用pre指向递归返回的list就进行了拼接
            pre.next=list;
            return reverseNode;
        }
    }
    //链表的反转
    public ListNode reverse(ListNode reverseNode){
        ListNode pre = null;
        while(reverseNode!=null){
            ListNode temp = reverseNode.next;
            reverseNode.next = pre;
            pre= reverseNode;
            reverseNode = temp;
        }
        return pre;
    }

2、迭代:时间复杂度O(n+k),空间复杂度O(1) 
思路:制造一个哨兵,进行每一层的反转后拼接
public ListNode reverseKGroup (ListNode head, int k) {
        //哨兵
        ListNode numpy = new ListNode();
        //用来当前段的最后一个节点
        ListNode numpy1 = numpy;
        //寻找下一段的起点
        ListNode node = head;
        //记录当前段的起点
        ListNode pre  = head;
        while (node!=null){
             int m = 0;
            while(m<k-1&&node!=null){
                node = node.next;
                m++;
            }
            //如果node=null了,那么证明已经不够K个进行反转了
            if(node==null){
                break;
            }
            else{
                //定位下一段的起点
                ListNode temp = node.next;
                 //断开当前段和下一段的关联
                node.next = null;
                //下一段的起点
                node = temp;
                //通过当前段的起点进行翻转
                ListNode reverseNode = reverse(pre);
                //上一段的最后一个节点指向翻转后的当前段
                numpy1.next=reverseNode;
                //记录当前段的最后一个节点
                numpy1 = pre;
                //pre更新为下一段的起点
                pre=node;
            }
            
        }
        //因为在循环中层断开过与后一段的关联
        //如果出现了后一段不足k个的情况应该将其重新关联起来
        numpy1.next = pre;
        return numpy.next;
    }
     public ListNode reverse(ListNode reverseNode){
        ListNode pre = reverseNode;
        reverseNode = reverseNode.next;
        while(reverseNode!=null){
            ListNode temp = reverseNode.next;
            reverseNode.next = pre;
            pre= reverseNode;
            reverseNode = temp;
        }
        return pre;
    }