idea:参考上一道全部反转,所以反转链表部分代码实现,我觉得重点在于集中不同情况的分类讨论。一共四类情况需要考虑,有前有后,有前无后,有后无前,无前无后。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode* p=head, *q=nullptr, *m=nullptr; //三个指针实现反转任务
ListNode* top=head; //top在有前的情况下记录“前指针”
int i=1;
while(p!=nullptr){ //传入有效链表
if(i==left-1){
top=head;
}
if(i==left)
q=head;
if(i>left && i<right+1){ //注意反转是从left+1项开始
m=head;
head=head->next;
m->next=q;
q=m;
i++;
continue;
}
if(i==right && head->next==nullptr){ //无后情况,分有前和无前
if(left==1){
return q;
}
else{
top->next->next=nullptr;
top->next=q;
return p;
}
}
if(i==right+1){ //有后情况,分有前和无前
if(left>1){
top->next->next=head;
top->next=q;
return p;
}
else{
top->next=head;
return q;
}
}
head=head->next;
i++;
}
return nullptr;
}
};
复杂度:
时间复杂度应该为O(n)
空间复杂度:应该为O(1)
进阶: ①递归反转 idea:上面使用的迭代法,还可以使用递归来实现反转的部分,代码略
②穿针引线 idea: 题解提供了一种新思路,遍历到反转部分是,将每个遍历的结点插入到反转部分的起点

class Solution {
public:
ListNode *reverseBetween(ListNode *head, int left, int right) {
// 设置 dummyNode 是这一类问题的一般做法
ListNode *dummyNode = new ListNode(-1);
dummyNode->next = head;
ListNode *pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
ListNode *cur = pre->next;
ListNode *next;
for (int i = 0; i < right - left; i++) {
next = cur->next;
cur->next = next->next;
next->next = pre->next;
pre->next = next;
}
return dummyNode->next;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】