public static ListNode reverseBetween(ListNode head, int m, int n) {

    if (head == null || n == 1) {
      return head;
    }

    ListNode dummy = new ListNode(0);
    dummy.next = head;

    ListNode mNode = dummy; // m-1 th node
    ListNode nNode = dummy.next; // n + 1 th node

    int count = 0;
    while (mNode != null && nNode != null) {
      count++;
      if (count < m) {
        mNode = mNode.next;
        nNode = nNode.next;
      } else if (count >= m && count < n) {
        nNode = nNode.next;
      } else { // count >= n
        break;
      }
    }
    nNode = nNode.next;

    ListNode prev = mNode;
    ListNode last = prev.next;
    ListNode curt = last.next;

    while (curt != nNode) {
      last.next = curt.next;
      curt.next = prev.next;
      prev.next = curt;
      curt = last.next;
    }

    return dummy.next;
  }