1. 分析
此题存在换头的可能。
- 先判断m、n是否合法,不合法则直接返回head。需要计算list length,过程中同时确定m-1(即mPre)和n+1(nNext)的位置。
- 循环反转m-n部分,先把m.next=nNext确定,而mPre.next需要反转结束后,根据m是否为头作不同选择。
- 如果m为头,则直接换头,否则mPre.next = n。
2. 代码
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
//计算length,同时把mPre和nNext找到出来
ListNode tmp = head;
ListNode mPre = null;
ListNode nNext = null;
int len = 0;
for(; tmp!=null; tmp = tmp.next){
len = len+1;
if(len == m -1) mPre = tmp;
if(len == n + 1) nNext = tmp;
}
//判断1<=m <= n <= length
if(m > n || m < 1 || n > len) return head;
//先把m-n反转,再设置mPre nNext的连接
//三个辅助指针用于反转
ListNode node1 = (mPre == null)?head : mPre.next;//指向m
ListNode node2 = node1.next;
ListNode node3 = null;
node1.next = nNext;//m的next指向n的next
//开始反转
while(node2 != nNext){
node3 = node2.next;
node2.next = node1;
node1 = node2;
node2 = node3;
}//循环结束,node1指向n
//判断是否换头,根据m是否为head
if(mPre == null){
return node1;
}else{
mPre.next = node1;
return head;
}
}
} 3. 复杂度
空间:O(1)
时间: O(n)



京公网安备 11010502036488号