解法一:双指针(两次遍历)

思路步骤:

  • 要反转局部链表,可以将该局部部分当作完整链表进行反转

  • 再将已经反转好的局部链表与其他节点建立连接,重构链表

  • 建议使用虚拟头节点的技巧,可以避免对头节点复杂的分类考虑,简化操作。

  • 反转前后图示:
    图片说明

  • 配图说明:
    图片说明

  • 反转步骤:
    图片说明

    Java参考代码:

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
       // 解法一:双指针(两次遍历)
       //说明:方便理解,以下注释中将用left,right分别代替m,n节点 

    public ListNode reverseBetween (ListNode head, int m, int n) {
             //设置虚拟头节点
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;

        ListNode pre = dummyNode;
        //1.走left-1步到left的前一个节点
        for(int i=0;i<m-1;i++){
            pre = pre.next;
        }

        //2.走roght-left+1步到right节点
        ListNode rigthNode = pre;
        for(int i=0;i<n-m+1;i++){
            rigthNode = rigthNode.next;
        }

        //3.截取出一个子链表
        ListNode leftNode = pre.next;
        ListNode cur = rigthNode.next;

        //4.切断链接
        pre.next=null;
        rigthNode.next=null;

        //5.反转局部链表
        reverseLinkedList(leftNode);

        //6.接回原来的链表