• 牛客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;
        }
    };
    
  • 相关阅读:
    【原创】常用元器件(电阻)选型之阻值有多少-cayden20220910
    01-win10安装Qt5
    接口测试步骤和场景分析,其实很简单~~
    Spring AOP实现原理及代理模式
    【luogu P7518】宝石(主席树)(二分)
    Redis 集群环境案例安装步骤
    《数据结构与算法》之十大基础排序算法
    flowable
    Please No More Sigma(构造矩阵)
    抖音 矩阵系统,牛视源码,抖音矩阵系统定制。
  • 原文地址:https://blog.csdn.net/qq_62321047/article/details/140451475