力扣 92 反转链表②【虚拟头结点】

力扣 82 反转链表② 【虚拟头结点】

全部刷题与学习记录

【C++刷题学习笔记目录】

【C++百万并发网络通信-笔记目录】

原题目

题目地址: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]

考查知识点

虚拟头结点可以避免对头结点进行操作的特殊情况分类讨论


自己的第一遍解法

思路确实是要保存反转链表的第一个节点leftNode与其前一个节点Pre、最后一个节点rightNode与其下一个节点endNext

但是做的不好的地方有两点:

1、没有想到用虚拟头结点来避免对操作头结点特殊性的讨论

2、没有想到将反转的子链表先截断再反转,导致头尾的处理十分复杂


好的解法

参考:

https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/fan-zhuan-lian-biao-ii-by-leetcode-solut-teyq/

思路仍然是:保存反转链表的第一个节点leftNode与其前一个节点pre、最后一个节点rightNode与其下一个节点endNext

但是加上了头结点、先截断后反转

需要复习的是:反转一般链表的方法reverseLinkedList(),还是需要一前一后两个指针,不断更改指针指向的节点的next

之前写的 剑指 24 反转链表 ,加了注释

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 {
    
    
private:
    //反转链表函数
    void reverseLinkedList(ListNode* head) {
    
    
        ListNode* pre = nullptr;
        ListNode* cur = head;

        while (cur != nullptr) {
    
    
            ListNode* next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
    }

public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
    
    
        //使用虚拟头结点避免对处理头结点的复杂分类讨论---重点
        ListNode* dummyHead = new ListNode(-1);
        dummyHead->next = head;
        ListNode* pre = dummyHead;

        //从虚拟头结点走left-1步,到leftPre
        for (int i = 0; i < left-1; ++i) {
    
    pre = pre->next;}

        //从pre走right-left+1步,到right
        ListNode* rightNode = pre;
        for (int i = 0; i < right-left+1; ++i) {
    
    rightNode = rightNode->next;}

        //取出并切断子链表
        ListNode* leftNode = pre->next;
        ListNode* endNext  = rightNode->next;
        pre->next = nullptr;
        rightNode->next = nullptr;

        //反转子链表
        reverseLinkedList(leftNode);

        //将反转后的链表拼接回去
        pre->next = rightNode;
        leftNode->next = endNext;

        return dummyHead->next;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44484715/article/details/114990214
今日推荐