反转链表的指定区域

2020-05-15  本文已影响0人  环宇飞杨

/*

*/

解题思路

凡是涉及反转的思路,都需要先打断链表重新组合,
如果反转指定区域,可以将中间需要选装的部分 截取出来 ,和剩余部分总共组成三段内容
比如链表:1->2->3->4->5->NULL,m = 3, n = 4可以拆分为:
左边:1->2
中间:3->4
右边:5->NULL

解题步骤

  1. 其中 左边一段 需要记录最后一个节点 p1,用于后续再将整个链表衔接起来
  2. 右边一段需要记录首节点 p2,同样用作后面衔接。
  3. 然后准备旋转中间链表
  1. 旋转后将p3节点指向p2 节点
  2. 最后将p1节点指向旋转后的链表
  3. 返回head节点,(所有的指针指向更改都是在操作head内部)

完。

注:有些case比较变态,会有m =1 的情况,此时要考虑无左边链表的情况,此时p1就应该等于head。
其余的:如果只有一个节点,再怎么玩都是一个,直接return head;
如果m = n,那么等于不需要旋转 ,也return head;

class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if (head.next == null) { //只有一个节点
            return head;
        }
        if (m == n) { //不需要旋转
            return head;
        }
        ListNode startNode = null; //p1
        ListNode endNode = null; //p2
        ListNode cur = head;
        int count = 0;
        while (cur != null) { //找出需要拆分的位置p1,p2
            count++;
            if (count == m - 1) {
                startNode = cur;
            }
            if (count == n + 1) {
                endNode = cur;
            }
            cur = cur.next;
        }
        ListNode fromNode = startNode==null?head: startNode.next;
        //旋转中间链表
        cur = fromNode;
        ListNode newHead = null;
        while (cur != endNode) {
            ListNode temp = cur.next;
            cur.next = newHead;
            newHead = cur;
            cur = temp;
        }

        fromNode.next = endNode; //拼接尾部
        if (startNode == null) {
            head = newHead;
        }else
        {
            startNode.next = newHead; //拼接头部
        }
        return head;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读