中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

劍指offer:復(fù)雜鏈表的復(fù)制-創(chuàng)新互聯(lián)

題目描述
輸入一個(gè)復(fù)雜鏈表(每個(gè)節(jié)點(diǎn)中有節(jié)點(diǎn)值,以及兩個(gè)指針,一個(gè)指向下一個(gè)節(jié)點(diǎn),另一個(gè)特殊指針指向任意一個(gè)節(jié)點(diǎn)),返回結(jié)果為復(fù)制后復(fù)雜鏈表的head。(注意,輸出結(jié)果中請不要返回參數(shù)中的節(jié)點(diǎn)引用,否則判題程序會(huì)直接返回空)

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供江陰企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站HTML5建站、小程序制作等業(yè)務(wù)。10年已為江陰眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。
# -*- coding: utf-8 -*-
# @Time         : 2019-07-05 15:52
# @Author       : Jayce Wong
# @ProjectName  : job
# @FileName     : complexListNodeClone.py
# @Blog         : https://blog.51cto.com/jayce1111
# @Github       : https://github.com/SysuJayce

class RandomListNode:
    def __init__(self, x):
        self.label = x
        self.next = None
        self.random = None

"""
    解法1:
    直接復(fù)制鏈表的話,由于每個(gè)節(jié)點(diǎn)有一個(gè)隨機(jī)指針指向任意的位置(包括空指針),因此如果用最樸素的方法
    來解決,需要在將所有節(jié)點(diǎn)復(fù)制完之后,對每個(gè)節(jié)點(diǎn)的random屬性遍歷一次整個(gè)鏈表,因此假設(shè)共有n個(gè)
    節(jié)點(diǎn),那么這種最樸素的解法的時(shí)間復(fù)雜度為O(n^2)

    解法2:
    解法1之所以效率低是因?yàn)槊總€(gè)節(jié)點(diǎn)的random指針的指向需要遍歷整個(gè)鏈表才能找到,如果我們犧牲空間來
    換時(shí)間的話,那么就可以做到時(shí)間復(fù)雜度為O(n), 額外使用空間O(n)。
    具體做法可以是用一個(gè)字典來保存每個(gè)節(jié)點(diǎn)及其對應(yīng)的克隆節(jié)點(diǎn)的地址,這樣就可以通過查詢這個(gè)哈希表在
    O(1)的時(shí)間內(nèi)找到random指針?biāo)赶虻墓?jié)點(diǎn)

    解法3:
    解法2之所以能把時(shí)間復(fù)雜度降下來,是因?yàn)楸4媪嗽脊?jié)點(diǎn)和對應(yīng)克隆節(jié)點(diǎn)的位置關(guān)系,因此可以很快找到
    原始節(jié)點(diǎn)對應(yīng)的克隆節(jié)點(diǎn)在哪。如果我們在復(fù)制鏈表的時(shí)候就讓克隆節(jié)點(diǎn)跟在原始節(jié)點(diǎn)后面,那么就可以在
    不額外使用哈希表的情況下做到時(shí)間復(fù)雜度為O(n)了
"""

class Solution2:
    def Clone(self, pHead):
        if not pHead:
            return None
        nodeTable = dict()  # 用于保存原始節(jié)點(diǎn)對應(yīng)的克隆節(jié)點(diǎn)的地址
        pClone = RandomListNode(pHead.label)
        # 由于節(jié)點(diǎn)類型無法哈希,因此用地址作為key
        nodeTable[id(pHead)] = pClone

        pNode = pHead
        pNode = pNode.next
        cloneNode = pClone
        # 這個(gè)循環(huán)用于將原始鏈表復(fù)制出來,但是先忽略random指針,關(guān)鍵在于要用這個(gè)字典保存
        # 原始節(jié)點(diǎn)和對應(yīng)克隆節(jié)點(diǎn)的地址
        while pNode:
            cloneNode.next = RandomListNode(pNode.label)
            nodeTable[id(pNode)] = cloneNode.next
            cloneNode = cloneNode.next
            pNode = pNode.next

        # 根據(jù)字典保存的信息設(shè)置克隆鏈表的random指針
        cloneNode = pClone
        while pHead:
            # 需要注意的是random指針可能是指向None,而我們在字典中并沒有保存None的key
            if pHead.random:
                cloneNode.random = nodeTable[id(pHead.random)]
            pHead = pHead.next
            cloneNode = cloneNode.next

        return pClone

class Solution3:
    def Clone(self, pHead):
        # 解法3的思路可以分為三步:
        # 1. 復(fù)制整個(gè)鏈表,這里先忽略random指針的指向,得到形如A->A'->B->B'->C->C'的復(fù)制結(jié)果
        # 2. 設(shè)置克隆節(jié)點(diǎn)的random指針
        # 3. 將鏈表拆分成原始鏈表和克隆鏈表
        self.cloneNode(pHead)
        self.connectSiblingNode(pHead)
        return self.reconnectNode(pHead)

    def cloneNode(self, pHead):
        pNode = pHead
        while pNode:
            pClone = RandomListNode(pNode.label)
            pClone.next = pNode.next
            pNode.next = pClone
            pNode = pClone.next

    def connectSiblingNode(self, pHead):
        pNode = pHead
        while pNode:
            clone_head = pNode.next
            if pNode.random:
                clone_head.random = pNode.random.next
            pNode = clone_head.next

    def reconnectNode(self, pHead):
        if not pHead:
            return None
        new_head = pHead.next
        pNode = new_head
        """
        這里不知為什么,如果把pHead指向new_head的左邊(即pHead和new_head分別指向A和A')
        然后進(jìn)入循環(huán)就不能通過??偷腛J,

        但是將pHead指向new_head的右邊(即pHead和new_head分別指向B和A')
        然后進(jìn)入循環(huán)就可以通過。

        這兩種方法在本地調(diào)試的時(shí)候都是沒問題的。
        """
        pHead.next = pNode.next
        pHead = pHead.next
        while pHead:
            pNode.next = pHead.next
            pNode = pNode.next
            pHead.next = pNode.next
            pHead = pHead.next

        return new_head

def main():
    # 1->3
    # 2->1
    # 3->2
    # node = RandomListNode(1)
    # node.next = RandomListNode(2)
    # node.next.next = RandomListNode(3)
    # node.random = node.next.next
    # node.next.random = node
    # node.next.next.random = node.next

    node1 = RandomListNode(1)
    node2 = RandomListNode(2)
    node3 = RandomListNode(3)
    node4 = RandomListNode(4)
    node5 = RandomListNode(5)
    node1.next = node2
    node2.next = node3
    node3.next = node4
    node4.next = node5
    node1.random = node3
    node2.random = node5
    node4.random = node2

    solution = Solution2()
    head = solution.Clone(node1)
    while head:
        if head.random:
            print(head.label, head.random.label)
        else:
            print(head.label, 'None')
        head = head.next

if __name__ == '__main__':
    main()

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

本文名稱:劍指offer:復(fù)雜鏈表的復(fù)制-創(chuàng)新互聯(lián)
分享路徑:http://m.rwnh.cn/article4/ccgoie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、外貿(mào)建站、網(wǎng)站設(shè)計(jì)公司軟件開發(fā)、網(wǎng)站收錄定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營
陈巴尔虎旗| 诸城市| 阳春市| 陈巴尔虎旗| 南川市| 南和县| 邯郸市| 古浪县| 雅江县| 江口县| 搜索| 洛川县| 临猗县| 红河县| 濉溪县| 琼海市| 宁陕县| 开原市| 抚松县| 阳曲县| 平原县| 枣强县| 措勤县| 南昌市| 乐亭县| 旬邑县| 西乌| 夏津县| 抚远县| 合水县| 长春市| 涟源市| 水城县| 绥化市| 赤壁市| 嘉祥县| 曲靖市| 台江县| 蒲城县| 望都县| 石阡县|