鏈表交叉重排(Leetcode143)

題目

  • 給定一個(gè)單鏈表從L0->L1->...->Ln-1->Ln將其重新排列為L(zhǎng)0->Ln->L1->Ln-1->L2->Ln-2->...
  • 舉例:輸入1->2->3->4, 重排為 1->4->2->3.

解法一(采用壓棧的方式)

  • 首先這個(gè)鏈表肯定是分段為兩部分,從中間斷開(kāi),而后面的是按照逆序插入到前半部分中的,如果是直接遍歷索引我們是無(wú)法做逆序插入的,鏈表只能從前往后索引不能從后往前
  • 就可以采用入棧的方式,將所有的鏈表壓入棧,此時(shí)棧頂元素就是鏈表最后一個(gè)節(jié)點(diǎn),依次就可以取得第n n-1 n-2個(gè)數(shù)
  • 然后我們從head.next開(kāi)始遍歷,從head節(jié)點(diǎn)開(kāi)始插入,每次從棧中取出一個(gè)元素插入到head鏈表中,然后再?gòu)膆ead.next的前鏈表中取出一個(gè)元素插入,完成整個(gè)鏈表的重排

棧的代碼實(shí)現(xiàn)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return;
        Stack<ListNode> stack = new Stack<>();
        ListNode index = head.next;
        while (index != null) {
            stack.push(index);
            index = index.next;
        }
        index = head.next;
        ListNode p = head;
        int count = 0;
        while (count < stack.size()) {
        //每一次count+1, stack-1整體變化為2
            p.next = stack.pop();
            p = p.next;
            p.next = index;
            index = index.next;
            p = p.next;
            count++;
        }
        p.next = null;
    }
}

解法二(快慢雙指針)

  • 解法三部曲
  • slow和fast分別從head開(kāi)始遍歷,slow每次移動(dòng)一個(gè)next,fast移動(dòng)兩個(gè)next,當(dāng)fast到達(dá)null結(jié)束循環(huán)時(shí),此時(shí)slow就是我們需要的第一個(gè)分段的最后一個(gè)數(shù)據(jù)。
  • 將此時(shí)slow之后的片段2進(jìn)行逆序重排比如1->2->3->4重排為1->2->4->3,因?yàn)榇藭r(shí)slow是指向2的。
  • 第三步,把數(shù)據(jù)按照前后交叉整合,即可得到最后的結(jié)果1->4->2->3
  • 空間復(fù)雜度O(1),時(shí)間復(fù)雜度O(n)

代碼二

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return;
        ListNode slow = head, fast = head;
        //找到前半部分鏈表
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        //后半段頭插法改變鏈表順序
        ListNode index = slow.next;
        slow.next = null;
        while (index != null) {
            ListNode temp = index;
            index = index.next;
            temp.next = slow.next;
            slow.next = temp;
        }
        //前后交叉合并為一個(gè)鏈表
        ListNode pre = head;
        index = slow.next;
        while (pre != slow) {
            slow.next = index.next;
            index.next = pre.next;
            pre.next = index;
            pre = index.next;
            index = slow.next;
        }
    }
}

參考鏈接

https://www.cnblogs.com/woainifanfan/p/6511943.html

?著作權(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)容

  • 搞懂單鏈表常見(jiàn)面試題 Hello 繼上次的 搞懂基本排序算法,這個(gè)一星期,我總結(jié)了,我所學(xué)習(xí)和思考的單鏈表基礎(chǔ)知識(shí)...
    醒著的碼者閱讀 4,734評(píng)論 1 45
  • //leetcode中還有花樣鏈表題,這里幾個(gè)例子,冰山一角 求單鏈表中結(jié)點(diǎn)的個(gè)數(shù)----時(shí)間復(fù)雜度O(n)這是最...
    暗黑破壞球嘿哈閱讀 1,658評(píng)論 0 6
  • 鏈表刪除[203] Remove Linked List Elements[19] Remove Nth Node...
    野狗子嗷嗷嗷閱讀 6,439評(píng)論 4 35
  • 教育孩子對(duì)于我來(lái)說(shuō)確實(shí)是個(gè)新手,對(duì)于很多人可能都和我一樣的。在教育的這個(gè)深度和廣度講,我們是不全面的。如果說(shuō)...
    行者之龍閱讀 446評(píng)論 0 0
  • 習(xí)慣張開(kāi)五指 擋住那刺眼的驕陽(yáng) 剎那問(wèn)候的溫柔 驚艷了過(guò)去的時(shí)光 這世上越相愛(ài)越彷徨 最后我懂了 歲月從不容許人荒唐
    雨初33閱讀 158評(píng)論 0 0

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