纠正思路
初始思路是用尾插法,遍历到要开始反转的第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;
}
}



京公网安备 11010502036488号