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类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
ListNode pre = new ListNode(-1);
pre.next = head;
ListNode newList = pre;
//前面是不需要反转的节点的遍历
for(int i = 1; i < m; i++){
pre = head;
head = head.next;
}
//下面是需要反转的节点,记录开始位置和第一个反转点(因为这个点事反转的最后一个点),需要这个点衔接后面不反转的点
ListNode mid = pre;
ListNode midRight = head;
for(int i = m; i<= n; i++){
ListNode tmp = head.next;
mid.next = head;
midRight.next = head.next;
if(pre != mid){
//避免循环
head.next = pre;
}
pre = head;
head = tmp;
}
return newList.next;
}
}
mid和midRight 的位置不动,head和pre相邻向前移动。mid的next和midRight的next向后移动,注意避免循环
另一种相似解法
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类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
//加个表头
ListNode newList = new ListNode(-1);
newList.next = head;
//前序节点
ListNode pre = newList;
//找到m
for(int i = 1; i < m; i++){
pre = head;
head = head.next;
}
//从m反转到n
for(int i = m; i < n; i++){
ListNode temp = head.next;
head.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
//返回去掉表头
return newList.next;
}
}
与方法1的区别在于反转的方式不一样
方法1引入了mid和midRight固定开始反转的位置和第一个反转的点,pre和head是相邻向前移动。
方法2中pre和head的位置是固定的,相当于方法1中的mid和midRight。不断移动pre的next和head的next

京公网安备 11010502036488号