演算法 總結部分深拷貝問題的解法

2021-10-16 08:22:52 字數 3099 閱讀 9299

133. 轉殖圖

138. 複製帶隨機指標的鍊錶

深拷貝問題之前我在練習回溯的時候也遇到過。

在滿足backtrack時,將temp中的內容放入ans裡,我用的以下語句:

輸出始終是空的,直至我看了其他人寫的**,才發現原來是指標的問題。

在上面第一種方法,我是將temp指向的位址放進了ans中,導致每次更該temp,ans中所有的元素都在跟著更改。

深拷貝也是一種類似的問題。

我們先看看138,隨機指標鍊錶。

給定乙個鍊錶,每個節點包含乙個額外增加的隨機指標,該指標可以指向鍊錶中的任何節點或空節點。

要求返回這個鍊錶的 深拷貝。 

我們用乙個由 n 個節點組成的鍊錶來表示輸入/輸出中的鍊錶。每個節點用乙個 [val, random_index] 表示:

val:乙個表示 node.val 的整數。

random_index:隨機指標指向的節點索引(範圍從 0 到 n-1);如果不指向任何節點,則為  null 。

示例 1:

輸入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]

輸出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

複製鍊錶的過程也跟開頭提到的方法類似,不能直接以賦值的形式去做,我們先用深度優先搜尋(dfs, depth first search)去實現乙個簡單的鍊錶深拷貝。

def deepcopylinkedlist(head:listnode) -> listnode:

if not head:

return head

copynode = node(head.val)

copynode.next = deepcopylinkedlist(head.next)

return copynode

我們在每個節點建立乙個新的node,讓新node.val跟我們要複製的節點位置的值一樣,在原位置節點的next指標複製進去,就實現了鍊錶的深拷貝。

那麼加上隨機指標後深拷貝有什麼不一樣了呢?

你所複製的隨機指標指向的節點,可能是被複製過的節點。

你所複製的節點,可能是被隨機指標指向的節點。

這兩句話很拗口啊,舉個例子:

例如上圖,第二個節點隨機指向了第乙個節點(索引從1開始)。當你深度優先複製完節點的時候,隨機指標又重新建立了乙個值為7的新節點,並沒有指向你所要的一節點,即:

這個時候,就需要用到乙個單獨的變數來儲存我們已經擁有過的節點,即雜湊表。

題解

"""

# definition for a node.

class node:

def __init__(self, x: int, next: 'node' = none, random: 'node' = none):

self.val = int(x)

self.next = next

self.random = random

"""class solution:

def __init__(self):

self.dic = {} # create a hashtable

def copyrandomlist(self, head: 'node') -> 'node':

# return if head is none

if not head:

return head

# judge if the node copied

if head in self.dic:

return self.dic[head]

# create a new node put it in hashtable

copynode = node(head.val)

self.dic[head] = copynode

# dfs

copynode.next = self.copyrandomlist(head.next)

copynode.random = self.copyrandomlist(head.random)

# recurtion

return copynode

同樣地,看一下轉殖圖。

一樣的做法,在做之前要充分理解這個圖的資料結構,否則一頭霧水。(我看題意就看了十分鐘,雖然知道是深拷貝....)

題解

"""

# definition for a node.

class node:

def __init__(self, val = 0, neighbors = none):

self.val = val

self.neighbors = neighbors if neighbors is not none else

"""class solution:

def __init__(self):

self.dic = {}

def clonegraph(self, node: 'node') -> 'node':

if not node:

return node

if node in self.dic:

return self.dic[node]

copynode = node(node.val, )

self.dic[node] = copynode

if node.neighbors:

copynode.neighbors = [self.clonegraph(n) for n in node.neighbors]

return copynode

深拷貝和淺拷貝的問題

不拷貝 賦值 舉個例子 let a let b a b.a 20 console.log a.a 20直接賦值的話,物件是指向同一記憶體,所以修改物件b的屬性,物件a的屬性同時也會改變 淺拷貝 object.assign 和解構賦值.舉個例子 let a let b object.assign a ...

OpenCV cv Mat的深拷貝 淺拷貝問題

目錄 先看結論 演示下 效果什麼樣 今天抽空整理了一下關於opencv中mat這個容器的深淺拷貝問題 什麼是深拷貝?什麼又是淺拷貝?而到了opencv的mat時,有幾種賦值方式分別為 1 b a.clone 2 a.copyto b 3 b a 4 b a 先給結論!先給結論!先給結論!深拷貝是 b...

賦值 淺拷貝 深拷貝 的區別總結

當我們把乙個物件賦值給乙個新的變數時,賦的其實是該物件的在棧中的位址,而不是堆中的資料。也就是兩個物件指向的是同乙個儲存空間,無論哪個物件發生改變,其實都是改變的儲存空間的內容,因此,兩個物件是聯動的。賦值 var obj1 var obj2 obj1 lisi 二 三 obj2.name lisi...