题解一:迭代翻转
题解思路 : 建立一个空白节点指向头节点,然后翻转[m,n]内的节点。
参数分析: p:指向m前一个节点,q指向第n个节点。p1,p2用于翻转.
图示:
图片说明
复杂度分析
时间复杂度:O(N),最多遍历整个链表
空间复杂度:O(1),只使用了常数个变量
实现如下:

class Solution {
public:
    /**
     *
     * @param head ListNode类
     * @param m int整型
     * @param n int整型
     * @return ListNode类
     */

    ListNode* reverseBetween(ListNode* head, int m, int n) {
        // write code here
          if(head==NULL||head->next==NULL||m==n) return head;
          struct ListNode* p;
          struct ListNode* q;
          struct ListNode* l;
          l = (struct ListNode*)malloc(sizeof(struct ListNode));  //创建空白节点
          l->next = head;  // 空白节点指向头节点
          p = q = l;
          for(int i =1;i<m;i++)
              p = p->next;  // p指向m前一个节点
          for(int i = 1;i<=n;i++)
              q = q->next; //q 指向第n个节点
          struct ListNode* p1 = p->next;  // p1 是第m个节点
          struct ListNode* p2 = p1->next;
          p->next = q; // m前一个节点要指向q
          p1->next = q->next;  
          while(p2!=q){  //反转节点
              p = p2->next;
              p2->next = p1;
              p1 = p2;
              p2 = p;
          }
          p2->next = p1;
          return l->next;
    }
};

题解二:递归
题解思路:利用反转链表的思想,使用递归
图示:反转链表的递归
图片说明

递归分析:
递归边界:n=1 tmp保存子问题的部分的next用于拼接
递归进行: (m-1,n-1)表示反转开始的位置在子问题中的节点开始位置
图示:
图片说明

复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N),最坏递归栈深度
实现如下:

class Solution {
public:
    ListNode* tmp = NULL;
    ListNode* reverseBetween(ListNode* head, int m,int n){
        if( m == 1) return reverse(head, n);
        ListNode* p = reverseBetween(head->next, m-1,n-1); // m,n在子问题中要减1
        head->next = p; //拼接反转之后的部分
        return head;
    }
    ListNode* reverse(ListNode* head,int n){
        if(n == 1){
            tmp = head->next;
            return head;
        }
        ListNode* new_head = reverse(head->next,n-1);  //子问题,位置要减1
        head->next->next = head; //反转 
        head->next = tmp;  //拼接尾部
        return new_head;
    }
};