[leetcode 92] 反转链表 II
题目描述:
https://leetcode.cn/problems/reverse-linked-list-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
进阶: 你可以使用一趟扫描完成反转吗?
解题思路:
https://www.bilibili.com/video/BV1sd4y1x7KN(视频讲解)
假设要反转链表中的节点2,3,4
首先,反转之后,从原链表(图中第二条链表蓝色和黑色部分)来看,反转段的上一个节点为p0,反转段的头节点为pre,反转段的后一个节点为cur
然后,处理反转段的前面和后面节点(图中粉色部分)
代码(C++/Python):
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: # 使用dummy防止left节点是链表头结点,简化代码逻辑 dummy=ListNode(next=head) p0=dummy #p0指向反转链表段的前一个节点 for _ in range(left-1): p0=p0.next pre=None cur=p0.next # 反转链表 for _ in range(right-left+1): nxt=cur.next cur.next=pre pre=cur cur=nxt # 处理反转段的前后结点 p0.next.next=cur p0.next=pre 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) { ListNode dummy(0,head); ListNode* p0=&dummy; for(int i=0;i<left-1;i++){ p0=p0->next; } ListNode* cur=p0->next; ListNode* pre=nullptr; ListNode* nxt=nullptr; for(int i=0;i<right-left+1;i++){ nxt=cur->next; cur->next=pre; pre=cur; cur=nxt; } p0->next->next=cur; p0->next=pre; return dummy.next;
解题总结:
注意,反转后的链表段,从原链表上看反转段其前后节点的位置,以及对其前后节点的处理。