【刷题笔记】牛客网:链表指定区间内反转
一、题目描述及示例
二、思路分析
1、首先,我们来定义一个虚拟的头节点tempHead(原因:如果从第一个位置开始反转,则可以不用进行特殊情况考虑),并使tempHead的next指向head
2、然后,我们定义两个ListNode型变量用来存储位置m的前一个节点和位置n的后一个节点,分别用pre和end表示;
创建mNode和nNode用来记录切割后链表的头和尾节点
3、遍历寻找到m的前一个节点的位置,并使用pre表示及m位置的节点,并使用mNode表示
4、遍历寻找到位置n的节点使用nNode表示及n的下一个节点,并使用end表示
5、对指定位置的链表进行切割
6、对切割后的链表进行反转
7、对反转后的链表进行拼接
8、最后,返回的是tempHead.next
三、代码实现如下
public ListNode ReverseBetween(ListNode head, int m, int n) {
//1、首先,我们来定义一个虚拟的头节点(原因:如果从第一个位置开始反转,则可以不用进行特殊情况考虑)
ListNode tempHead = new ListNode(-1);
tempHead.next = head;
//注意:此时tempHead是新的头节点(不能动它!!!),所以我们需要创建一个新的节点p,这样循环的时候我们就移动p即可
ListNode p = tempHead;
//2、然后,我们定义两个ListNode型变量用来存储位置m的前一个节点和位置n的后一个节点
ListNode pre;
ListNode end;
//创建mNode和nNode用来记录切割后链表的头和尾节点
ListNode mNode;
ListNode nNode;
//3、遍历寻找到m的前一个节点的位置,并使用pre表示及m位置的节点,并使用mNode表示
for (int i = 0; i < m-1; i++) {
p = p.next;
}
pre = p;
mNode = p.next;
//4、遍历寻找到位置n的节点使用nNode表示及n的下一个节点,并使用end表示
for (int i = 0; i < n-m+1; i++) {
p = p.next;
}
nNode = p;
end = p.next;
//5、对指定位置的链表进行切割
pre.next = null;
nNode.next = null;
//6、对切割后的链表进行反转
Reverse(mNode);
//7、对反转后的链表进行拼接
pre.next = nNode;
mNode.next = end;
//8、最后,返回的是tempHead.next
return tempHead.next;
}
//此处使用的头插法进行链表的反转,也可使用栈结构(看我博客的上一篇文章有)
public ListNode Reverse(ListNode head) {
ListNode newHead = null;
ListNode tmp;
while (head != null) {
//传教tmp节点用于记录head的next节点
tmp = head.next;
//使用头插法
head.next = newHead;
newHead = head;
head = tmp;
}
return newHead;
}