LeetCode-092-反轉(zhuǎn)鏈表II

反轉(zhuǎn)從位置 m 到 n 的鏈表。請(qǐng)使用一趟掃描完成反轉(zhuǎn)。

說(shuō)明:
1 ≤ m ≤ n ≤ 鏈表長(zhǎng)度。

示例:

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

來(lái)源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-linked-list-ii

解題思路

首先解決翻轉(zhuǎn)整個(gè)鏈表的問(wèn)題,給定一個(gè)頭節(jié)點(diǎn),將其所在鏈表翻轉(zhuǎn)
需要有三個(gè)變量來(lái)記錄翻轉(zhuǎn)過(guò)程,pre cur next
分別代表原順序的"上一個(gè)" "當(dāng)前這個(gè)" "下一個(gè)"
現(xiàn)將cur置為頭節(jié)點(diǎn),pre置為空
當(dāng)cur不為空時(shí)循環(huán)

  • 記錄nextcur.next
  • cur.next = pre將當(dāng)前節(jié)點(diǎn)的下一個(gè)指向前一個(gè)節(jié)點(diǎn)
  • pre = cur
  • cur = next 后面兩步起到迭代的作用

循環(huán)結(jié)束時(shí)pre就是新的頭節(jié)點(diǎn)
然后解決翻轉(zhuǎn)一個(gè)鏈表中的一部分
需要將鏈表分為三部分,翻轉(zhuǎn)的前驅(qū)部分,翻轉(zhuǎn)部分,翻轉(zhuǎn)的后繼部分
為了方便處理m = 1也就是從頭結(jié)點(diǎn)開(kāi)始翻轉(zhuǎn)這種情況,使用一個(gè)假的頭結(jié)點(diǎn)dummy
使dummy.next = head
然后從dummy開(kāi)始往后找n次,找到翻轉(zhuǎn)部分的尾節(jié)點(diǎn),記錄該尾節(jié)點(diǎn)的后繼節(jié)點(diǎn)nextNode,以便翻轉(zhuǎn)后連接上翻轉(zhuǎn)的后繼部分
接著從dummy開(kāi)始往后找m - 1次,找到翻轉(zhuǎn)的前驅(qū)部分的尾節(jié)點(diǎn)并記錄,該節(jié)點(diǎn)的next就是翻轉(zhuǎn)部分的頭節(jié)點(diǎn)
將翻轉(zhuǎn)部分的頭節(jié)點(diǎn)傳給翻轉(zhuǎn)方法,傳遞參數(shù)的頭節(jié)點(diǎn)在翻轉(zhuǎn)后變?yōu)槲补?jié)點(diǎn),將該節(jié)點(diǎn)的next設(shè)為上述記錄的nextNode
翻轉(zhuǎn)方法返回節(jié)點(diǎn)是翻轉(zhuǎn)后的翻轉(zhuǎn)部分頭節(jié)點(diǎn),所以翻轉(zhuǎn)的前驅(qū)部分的尾節(jié)點(diǎn)的next設(shè)為該節(jié)點(diǎn)
返回dummy.next

代碼

class Solution {
    private ListNode reverse(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }

    public ListNode reverseBetween(ListNode head, int m, int n) {
        if (head == null || head.next == null || m == n) {
            return head;
        }
        // 輔助頭節(jié)點(diǎn)
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode cur = dummy;
        // 找出要翻轉(zhuǎn)部分的尾節(jié)點(diǎn)
        for (int i = 0; i < n; i++) {
            cur = cur.next;
        }
        // 結(jié)束for后cur是要翻轉(zhuǎn)的尾節(jié)點(diǎn)
        // 保存該節(jié)點(diǎn)的后繼
        ListNode next = cur.next;
        // 斷開(kāi)以便反轉(zhuǎn)
        cur.next = null;
        cur = dummy;
        // for結(jié)束后cur的下一個(gè)是要翻轉(zhuǎn)的部分的頭節(jié)點(diǎn)
        for (int i = 0; i < m - 1; i++) {
            cur = cur.next;
        }
        ListNode start = cur.next;
        // 翻轉(zhuǎn)后start是翻轉(zhuǎn)部分的尾節(jié)點(diǎn)
        ListNode reverseHead = reverse(cur.next);
        cur.next.next = next;
        cur.next = reverseHead;
        return dummy.next;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容