public static ListNode reverseKGroup(ListNode head, int k) {
        int count = 0;
        ListNode p = head;
        while (p != null) {
            count ++;
            p = p.next;
        }
        
        // special case
        if (count < k || k == 1) {
            return head;
        }
        
        // loop count
        int loopCount = count / k;
        
        // local variable
        ListNode safeNode = new ListNode(Integer.MAX_VALUE);
        safeNode.next = head;
        
        ListNode pre = safeNode;
        ListNode cur = head;
        
        for (int i = 0; i < loopCount; i ++) {
            ListNode tmp = reverseK(cur, k);
            pre.next = tmp;
            
            ListNode tmpPre = null;
            ListNode tmpCur = tmp;
            
            for (int j = 0; j < k; j ++) {
                tmpPre = tmpCur;
                tmpCur = tmpCur.next;
            }
            
            pre = tmpPre;
            cur = tmpCur;
        }
        
        return safeNode.next;
    }