[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;

 

解题总结:

注意,反转后的链表段,从原链表上看反转段其前后节点的位置,以及对其前后节点的处理。

posted @ 2024-10-04 11:22  Makerr  阅读(8)  评论(0编辑  收藏  举报