题解 | #链表内指定区间反转#
链表内指定区间反转
https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c
public ListNode reverseBetween (ListNode head, int m, int n) {
//定义返回结果
ListNode resultHead = head;
//当m == n时 直接返回首节点
if(m == n) {
return head;
}
//找到m之前的节点和n之后的节点 以及m和n两个位置的节点
ListNode mNode = null;
ListNode nNode = null;
ListNode preNode = null;
ListNode tempNode = null;
ListNode lastNode = null;
//正常情况 m n 不是首节点和尾节点的情况
//定义指针变量 用来计数
int i = 1;
while(i < n){
//已经排除m与n相等的情况,可以直接先找到m
if(i == m){
//存在一种特殊情况,当m=1 此时preNode直接就是首届点
//此时可以为mNode赋值
preNode = tempNode;
mNode = head;
}
//记录上一个节点
tempNode = head;
head = head.next;
i++;
}
//循环结束,进入m之前的节点和n出来之后的节点都可以计算出来
if(head.next != null){
lastNode = head.next;
head.next = null;
}
//开始反转
ListNode reverse = ReverseList(mNode);
//反转结束 确定反转后m和n位置的节点
if(preNode == null){
//说明m就是首节点的位置
resultHead = reverse;
}else{
preNode.next = reverse;
}
if(lastNode != null){
while(reverse.next != null){
reverse = reverse.next;
}
//说明n就是首页点的位置,不需要做任何操作
reverse.next = lastNode;
}
return resultHead;
}
public ListNode ReverseList(ListNode head) {
if(head == null || head.next == null){
//当确保时节点的最后一个节点时作为方法返回值返回
return head;
}
ListNode resultNode = ReverseList(head.next);
head.next.next = head;
head.next = null;
return resultNode;
}解题思路:
1、借助在BM1题目中写的翻转链表的方法
2、特殊请款判断 m与n是否相等 如果相等直接返回传入head即可
3、根据0 <= m <= n < size的条件,之前已经排除了m和m相等的情况,只需要得到m和n两个位置的节点即可
4、找到两个位置节点的同时,记录m的上一个节点和n的下一个节点
5、将n位置的下一个节点设置为空,然后将m节点作为参数传入BM1方法中去,得到反转之后的链表
6、在将反转之后的链表首位节点加上即可

