自学内容网 自学内容网

牛客TOP101:链表内指定区间反转

1. 题目描述

在这里插入图片描述

2. 解题思路

  在做这道题之前希望大家先把链表翻转这个题写一下。
  这道题和反转链表的区别在于:它仅仅只翻转其中的某一个区间,但是我们可以将问题进行转化,转化为翻转链表。
  我们可以将翻转区间之外的部分先忽略掉,这样问题就转化为了翻转整个链表。在翻转完成后,在将剩余的部分连接起来就可以了。
  在连接时需要注意: 如果翻转的区间包含了头节点,那么翻转之后的函数返回值就不再时原来的头节点了,而是我们翻转之后的结点(做过翻转链表这个题就知道为什么了),如果翻转区间不包含头节点,那么最终的返回值依旧是原来的头节点。(因此这里是需要进行判断的)
  我在代码实现部分详细说明的每一步的代码意义,相信会对大家有所帮助。
在这里插入图片描述

3. 代码实现

/**
 * struct ListNode {
 *int val;
 *struct ListNode *next;
 *ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* reverseBetween(ListNode* head, int m, int n) {
    // 如果链表为空或者翻转区间只有一个结点,直接返回
        if(head == nullptr || (m == n)) return head;

// left结点的意义:翻转区间的第一个结点
// right结点的意义: 翻转区间的最后一个结点
// begin结点的意义: 翻转区间前的结点
        ListNode *left = head, *right = head, *begin = nullptr;
        // 找到left
        for(int i = 1; i < m; i++)
        {
        // 重点:如果翻转区间从1开始,也就是包含了头节点
        //      那么这个循环就不会进去
        //      那么begin的值就是nullptr —— 会方便后续的判断
            begin = left;  
            left = left->next;
        }
        // 找到right
        for(int i = 1; i < n; i++)
        {
            right = right->next;
        }

// tail结点的意义:翻转区间后面的结点
        ListNode* tail = right->next;

// 标记第一个进行翻转的结点(与链表翻转一题的写法一致)
        ListNode* cur = left, *prev = begin, *next = cur->next;

        int num = n - m + 1;  // 需要翻转的结点数
        // while(num--)
        for(int i = 1; i <= num; i++)
        {
            cur->next = prev;
            prev = cur;
            cur = next;
            if(next)
                next = next->next;
        }

        // 如果翻转的范围不包括头节点,那么就进行连接
        if(begin != nullptr)
        {
            begin->next = right;
            left->next = tail;
            return head;
        }

        // 到这里说明翻转的范围包括了头节点,那么就意味这返回的结点不再是原来的头节点了,返回的是翻转完成之后的结点
        // 同时需要考虑尾部是否还有结点
        if(tail != nullptr)
        {
            left->next = tail;        
        }
        return prev;
    }
};

原文地址:https://blog.csdn.net/qq_62321047/article/details/140451475

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!