Leetcode 92. 反转链表Ⅱ
初次写代码时,被边界条件各种ban,总是忽略,遂放弃,以下整理出一些评论区大佬边界条件不明显或不需要边界条件的解法。边界条件繁琐的代码不要背,否则笔试各种ban。
比较经典的是下面这种写法,有点抽象,根本思想是有三个指针:
第一个指针在反转段前一个节点固定;
第二个指针是当初的第一个需要反转的节点,每次循环向右移动一个,最后被移动到反转段的尾部;
第三个指针是需要第二个指针当前所指的下一个指针,被搬运到第一个指针的指向节点的后面。
/** * 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 *dummy = new ListNode(-1); dummy->next = head; ListNode *pre = dummy; for(int i = 1; i < left; i ++ ){ pre = pre->next;//此时pre在left的左边 } head = pre->next; for(int i = left; i < right; i ++ ){ ListNode *nex = head->next; head->next = nex->next; nex->next = pre->next; pre->next = nex; //从pre->...->head->nex,变成pre->next->...->head } return dummy->next; } };
第二种方法非常妙。里面没有改变指针的指向关系,而是改变了节点的值,每一次循环都将当前遍历到节点的值交换到反转段的末尾。
/** * 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) { int idx = right - left; ListNode *p = head; int pos = 1; while(pos < left){ p = p->next; ++ pos; } while(idx > 0){ ListNode *q = p; for(int i = 0; i < idx; i ++ ){ int tmp = q->val; q->val = q->next->val; q->next->val = tmp; q = q->next; } idx --; } return head; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?