题目:92. 反转链表 II
难度: 中等
题目:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例1
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
示例2
输入:head = [5], left = 1, right = 1
输出:[5]
提示
- 链表中节点数目为 n
- 1 <= n <= 500
- -500 <= Node.val <= 500
- 1 <= left <= right <= n
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
(1)将链表的某部分内容反转,类似于206.反转链表,所以可以沿着之前的思路。首先,找到需要反转的位置,然后开始利用迭代的方法将链表反转,知道right的位置。之后,将剩余的头和尾与反转的链表连接起来,这里需要考虑四种情况:(1)头开始尾结束 (2)非头开始尾结束 (3)头开始非为结束 (4)非头开始非为结束。每种不同的情况,连接的方式都不同。当然也可以利用虚拟结点,就不用考虑这些情况了。
(2)可以利用头插法的思想,每次都将需要改变的结点插入头部。实现算法时,第一个结点不动,操作后一个结点,第一个结点用于指向下下个结点。
解题代码
(1)暴力法
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode *p = head;
ListNode *pre = nullptr;
ListNode *last = nullptr;
ListNode *first = nullptr;
ListNode *newback = nullptr;
int i = 0;
while(p != nullptr)
{
i++;
if(left != 1 && i == left - 1)
{
first = p;
}
if(i == left)
{
newback = p;
}
if(i >= left && i <= right)
{
ListNode *s = p->next;
p->next = pre;
pre = p;
p = s;
}
else
{
p = p->next;
}
if(i == right)
{
last = p;
if(first == nullptr)//占第一个
{
if(p == nullptr)//最后一个
{
head = pre;
break;
}
else
{
newback->next = p;
head = pre;
break;
}
}
else
{
if(p == nullptr)//最后一个
{
first->next = pre;
break;
}
else
{
first->next = pre;
newback->next = p;
break;
}
}
}
}
return head;
}
};
(2)头插法一次遍历
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
//建立虚拟头结点,方便解决
ListNode *dummyNode = new ListNode(-1);
dummyNode->next = head;
ListNode *p = dummyNode;
ListNode *pre = dummyNode;
for(int i = 0; i < left - 1; i++)//p指向left前一个
p = p->next;
pre = p;//top
p = p->next;
for(int i = 0; i < right - left; i++)
{
ListNode *next = p->next;//当前结点的下一结点
p->next = next->next;//当前结点的下一结点为下一结点的下一结点,根据本题性质,是有存在的
//下面对下一结点操作
next->next = pre->next;//不能用p,因为p即第二个结点用于存储下一结点用,不能用p代
pre->next = next;
}
return dummyNode->next;
}
};
解题感悟
通过该题学习,发现之前的基础是如何重要(普通的反转链表方法)。同时,运用头插法解题时,因为为了让算法简单,采取了多个指针,看的头晕。。。但是多画图,其中的奥妙还是可以掌握的。