有个链表每个节点有随机指针,可以指向任何节点,也可以指向null,深拷贝这个链表
首先我是一个链表xiao白,每次看到链表思维混乱,逻辑混乱,指针指来指去,节点换来换去,但是因为大神每天都发链表的题~所以只能一直看各种题解,各种百度,最后总结出来自己的一点思路,希望帮助和我一样的链表xiao白更容易理解并且快速编程
当看到一道题,首先应该熟练掌握题目,然后熟练掌握思路,最后再分步骤进行编程设计代码,先说一下我入的坑,要知道每个节点都有一个random!然后原题目:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list.
这是一道英文题。。。简单翻译一下,有一个链表,每个节点有一个随机指针random可以指向任何节点也可以指向null,然后深拷贝这个链表
小知识
一:简单了解深拷贝和浅拷贝:(只是简单理解,想要继续深入理解自行百度)
1、浅拷贝:如果对象的属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型(引用地址),拷贝的就是这个内存地址(引用1->y引用1),如果原对象对该内存地址进行改变,那么拷贝后的对象该引用类型属性的内存地址也会改变。
2、深拷贝:深拷贝会拷贝对象的所有属性,如果属性是引用类型,也会被拷贝(引用1->引用2),这样原对象对该内存地址进行改变,也不会影响到另一个拷贝后的对象。
二:单纯的复制一个单链表,例如链表A->B,分以下几步:
1、 复制节点A为A'
2 、如果A节点的指针指向B,那么再复制B->B',
3 、然后A=A.next,继续往下遍历,如果A不为空,那么就继续复制
如果只是单纯的复制链表是不难的,但是本道题 中每个节点有一个random指针,所以上面的方法复制random和复制next会重复,并且也没有检查random指向的节点是否存在新链表,中所以不难看出本题的难点在于每个节点的random指针的重新定位,要考虑到random指向的节点是否已经被建立过,是否存在于新的链表中
本题思路
第一种方法<时间复杂度O(N),空间复杂度O(N),会占用额外的O(N)的空间>
使用哈希表(又名散列表),将原节点为键,新节点为值,这样就可以以O(1)的时间在新链表中找到next或者random指针指向的节点
第二种方法<时间复杂度O(N),空间复杂度O(1)>
在旧链表中创建新链表,如旧链表是1->2->3->4,创建之后是1->1'->2->2'->3->3'->4->4',而在第二次遍历链表的时候,如果节点4的random指针指向节点1,那么就让节点4'的random指针指向节点1',最后遍历新的链表,将新的节点取出来,参考以下图片便于理解:
代码如下:
总结~如果还有小白不能理解,那么就耐心花时间研究一下,百度多查一查,多做练习,这样即使再难的题再难理解的代码慢慢一定都会熟练掌握的~~