【刷题笔记】牛客网:链表指定区间内反转

【刷题笔记】牛客网:链表指定区间内反转

一、题目描述及示例

【刷题笔记】牛客网:链表指定区间内反转_第1张图片

二、思路分析

1、首先,我们来定义一个虚拟的头节点tempHead(原因:如果从第一个位置开始反转,则可以不用进行特殊情况考虑),并使tempHead的next指向head
2、然后,我们定义两个ListNode型变量用来存储位置m的前一个节点和位置n的后一个节点,分别用pre和end表示;
创建mNode和nNode用来记录切割后链表的头和尾节点
3、遍历寻找到m的前一个节点的位置,并使用pre表示及m位置的节点,并使用mNode表示
4、遍历寻找到位置n的节点使用nNode表示及n的下一个节点,并使用end表示
5、对指定位置的链表进行切割
6、对切割后的链表进行反转
7、对反转后的链表进行拼接
8、最后,返回的是tempHead.next

三、代码实现如下

public ListNode ReverseBetween(ListNode head, int m, int n) {
        //1、首先,我们来定义一个虚拟的头节点(原因:如果从第一个位置开始反转,则可以不用进行特殊情况考虑)
        ListNode tempHead = new ListNode(-1);
        tempHead.next = head;
        //注意:此时tempHead是新的头节点(不能动它!!!),所以我们需要创建一个新的节点p,这样循环的时候我们就移动p即可
        ListNode p = tempHead;

        //2、然后,我们定义两个ListNode型变量用来存储位置m的前一个节点和位置n的后一个节点
        ListNode pre;
        ListNode end;
        //创建mNode和nNode用来记录切割后链表的头和尾节点
        ListNode mNode;
        ListNode nNode;

        //3、遍历寻找到m的前一个节点的位置,并使用pre表示及m位置的节点,并使用mNode表示
        for (int i = 0; i < m-1; i++) {
            p = p.next;
        }
        pre = p;
        mNode = p.next;

        //4、遍历寻找到位置n的节点使用nNode表示及n的下一个节点,并使用end表示
        for (int i = 0; i < n-m+1; i++) {
            p = p.next;
        }
        nNode = p;
        end = p.next;

        //5、对指定位置的链表进行切割
        pre.next = null;
        nNode.next = null;

        //6、对切割后的链表进行反转
        Reverse(mNode);

        //7、对反转后的链表进行拼接
        pre.next = nNode;
        mNode.next = end;

        //8、最后,返回的是tempHead.next
        return tempHead.next;
    }

//此处使用的头插法进行链表的反转,也可使用栈结构(看我博客的上一篇文章有)
    public ListNode Reverse(ListNode head) {
        ListNode newHead = null;
        ListNode tmp;
        while (head != null) {
            //传教tmp节点用于记录head的next节点
            tmp = head.next;
            //使用头插法
            head.next = newHead;
            newHead = head;
            head = tmp;
        }
        return newHead;
    }

你可能感兴趣的:(链表,笔记,数据结构)