反转单链表中的子链表(Java实现)

本解题方法可能有点啰嗦,也不是最优解法,但是我自认为还是比较好理解的。

题目描述:

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

说明:
1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

解题思路:

  1. 首先我们需要写出一个能反转整个链表的工具方法。
  2. 然后开始判断需要反转的链表是哪一部分。共分为四种情况。先算出链表的长度:count
    1. 第一种情况:要反转的链表刚好是原链表(m == 1 && n == count)
    2. 第二种情况:要反转的链表和原链表的头节点相同,尾节点不同(m == 1 && n < count)
    3. 第三种情况:要反转的链表和原链表的头节点不同,尾节点相同 (m > 1 && n == count)
    4. 第四种情况:要反转的链表和原链表的头节点、尾节点均不相同(m > 1 && n < count)
  3. 根据以上四种情况。找到左边不需要反转的链表的尾节点,需要反转的链表的头节点,,右边不需要反转的链表的头节点。反转后链表的尾节点。然后将他们连接起来。
  4. 返回最终链表的头节点。

解题代码:

public static ListNode reverseNode(ListNode head) { //反转全部链表
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode f = head;
        ListNode s = f.next;
        while (s != null) {
            f.next = s.next;
            s.next = dummyHead.next;
            dummyHead.next = s;
            s = f.next;
        }
        return dummyHead.next;
}
public static ListNode reverseBetween(ListNode head, int m, int n) {
        if (head == null || head.next == null) {
            return head;
        }
        //计算链表的长度
        int count = 0;
        ListNode t = head;
        while (t != null) {
            count++;
            t = t.next;
        }
        ListNode dummyHead = head;
        if (m == 1 && n == count) {
            return reverseNode(head);
        }else if (m == 1 && n < count) {
            //找到需要反转的链表的尾节点
            ListNode temp = dummyHead;
            for (int i = 0; i < n-m; i++) {
                temp = temp.next;
            }
            //找到右边不需要反转的链表的头节点
            ListNode secondHead = temp.next;
            temp.next = null;
            dummyHead = reverseNode(dummyHead);
            //找到反转后链表的尾节点
            ListNode newNode = dummyHead;
            while (newNode != null) {
                if (newNode.next == null) {
                    break;
                }
                newNode = newNode.next;
            }
            //将反转后的链表跟右边没有反转的链表连接起来
            newNode.next = secondHead;
            return dummyHead;
        }else if (m > 1 && n == count) {
            ListNode firstTailNode = dummyHead;
            for (int i = 1; i < m-1; i++) {
                firstTailNode = firstTailNode.next;
            }
            //找到需要反转的链表的头节点
            ListNode reverseHead = firstTailNode.next;
            firstTailNode.next = null;
            reverseHead = reverseNode(reverseHead);
            //将左边不需要反转的链表跟反转后的链表连起来。
            firstTailNode.next = reverseHead;
            return head;
        }else {
            //找到左边不用反转的链表的尾节点firstTailNode。
            ListNode firstTailNode = dummyHead;
            for (int i = 1; i < m-1; i++) {
                firstTailNode = firstTailNode.next;
            }
            //找到需要反转的链表的头节点
            ListNode reverseHead = firstTailNode.next;
            firstTailNode.next = null;
            ListNode temp = reverseHead;
            //找到需要反转的链表的尾节点
            for (int i = 0; i < n-m; i++) {
                temp = temp.next;
            }
            //如果需要反转的链表的尾节点是整个链表的尾节点
            if (temp.next == null) {
                reverseHead = reverseNode(reverseHead);
                firstTailNode.next = reverseHead;
                return head;
            }else {
                //找到右边不用反转的链表的头节点
                ListNode secondHead = temp.next;
                temp.next = null;
                reverseHead = reverseNode(reverseHead);
                //找到反转后链表的尾节点
                ListNode newNode = reverseHead;
                while (reverseHead != null) {
                    if (reverseHead.next == null) {
                        break;
                    }
                    reverseHead = reverseHead.next;
                }
                //反转后的链表接上后面的链表
                reverseHead.next = secondHead;
                //前面的链表接上反转后的链表
                firstTailNode.next = newNode;
                return head;
         }
     }
 }

猜你喜欢

转载自blog.csdn.net/weixin_43573824/article/details/88550963