纠正思路
初始思路是用尾插法,遍历到要开始反转的第m个位置时,保存好第m个位置的前一个节点和当前节点作为反转后的最后一个节点,以便于反转后和前面以及后面的节点进行连接,但是这样当反转是从第一个节点开始时,就很难处理空指针的问题,所以还是用头插法比较好。
头插法需要设置一个额外的表头节点,其next指针永远指向链表第一个节点,初始时pre节点为表头节点,这样就可以在从第一个节点开始反转时也不会为空,遍历到要反转的位置后,pre就作为一个临时表头节点,指向反转后的第一个节点,current就作为反转后的最后一个节点,逐个将节点插到pre的后面,current前面。
参考
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @param m int整型 * @param n int整型 * @return ListNode类 */ public ListNode reverseBetween (ListNode head, int m, int n) { // write code here // 尾插法难处理起始位置在第一个节点的情况,因此用头插法反转链表 ListNode res = new ListNode(-1); // 头插法需要一个表头节点,其next指向最新的第一个节点 ListNode current = head; ListNode pre = res; // pre初始时指向表头节点,因此链表从第一个节点反转时,也不会导致pre为null ListNode temp = null; int index = 1; res.next = head; if (head.next == null) { return head; } while(index < m) { pre = current; current = current.next; index++; } // 找到第m个位置的节点后,pre是第m个位置的前一个节点,其next节点指向每一次反转的新的头节点 while(index < n) { // 头插是将current后面的节点插到current前面,因此不处理current,index不用等于n。 temp = current.next; current.next = temp.next; // current为反转后的最后一个节点,也是不变的 temp.next = pre.next; pre.next = temp; // pre保持不变,改变的是next指向的第一个节点的指针 index++; } return res.next; } }