力扣原题:
先贴代码:
public class Solution92 {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode newhead = new ListNode(-1);
newhead.next = head;
ListNode cur = newhead;
for (int i = 0; i < left-1; i++) {
cur = cur.next;
}
ListNode ret = cur.next;
for (int i = 0; i < right-left; i++) {
ListNode retNext = ret.next;
ListNode curNext = cur.next;
cur.next = retNext;
ret.next = retNext.next;
retNext.next = curNext;
}
return newhead.next;
}
}
思路分析:
题目中告诉我们,要求将链表中位置left到位置right之间的链表进行反转操作;例如left设为2,right设为4,那么意思如下图演示:
首先我们遇到这题解题时首先想到的反转方法应该是将位置为left节点(后简称为left节点)的前驱节点指向位置为right节点(后简称为right节点),再将left节点指向right节点的后继节点,然后再分别将这条链表内各节点的指向更改为前一个节点。但是这个方法未免过于复杂冗余,需要找到left节点和right节点,并且再进行遍历将链表中每个节点的指向更改。
我们在平时生活中肯定遇到过插队现象:每一个人都想往前面插,这样来一个人插一次队来一个人插一次队,慢慢的最前面的人就被挤到后面去了,这一题的解法也是类似的;
将在left位置后面的每一个节点都插入队伍的最前面,直至left节点成为最后一个节点(这里最后一个节点指的是这一条需要反转的链表的最后一个节点,并非一整条链表的最后一个;队伍的最前面也同理,是指需要反转的链表的最前面),这样我们只需要一次遍历链表就完成了反转链表的操作。具体操作如下图:
这里为了处理头节点也需要反转的情况,引入了一个虚拟头节点,方便解题:
然后创建cur节点使其指向left节点的前驱节点:
之后开始遍历链表:
最后返回新建的虚拟头节点的next节点: