{"id":1967,"date":"2024-03-12T16:00:00","date_gmt":"2024-03-12T16:00:00","guid":{"rendered":"https:\/\/favtutor.com\/articles\/?p=1967"},"modified":"2024-03-14T10:13:48","modified_gmt":"2024-03-14T10:13:48","slug":"copy-list-with-random-pointer","status":"publish","type":"post","link":"https:\/\/favtutor.com\/articles\/copy-list-with-random-pointer\/","title":{"rendered":"Copy List with Random Pointer Problem (with Solution)"},"content":{"rendered":"\n<p>Linked List is always a complex subject to crack for beginners. The problems asked in technical interviews are even more difficult, but not impossible. In this article, we will solve the Copy list with random pointers problem, with implementation in C++, Java, and Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Copy List with Random Pointer problem<\/strong><\/h2>\n\n\n\n<p>Before moving forward, remember that there are two different methods to copy a node in a linked list. <\/p>\n\n\n\n<p>One is a shallow copy in this you create a node whose address is the same as the original node. So if you made any changes in this it will also reflect in the original node. Another way is a deep copy in this you create a node and copy the values of the original node.<\/p>\n\n\n\n<p><strong>In the Copy List with Random Pointer problem, we are given a linked list with an additional random pointer that can point to any node. We need to create a deep copy of this linked list in which none of the nodes have the same address as the original list.\u00a0<\/strong><\/p>\n\n\n\n<p>Let\u2019s look at the example for more clarity:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/9PQKbQM4bCAgliZtTTW0Dt3rOPX8myhdhJFvB6Ndx05vjOu8yVMn18czF-izFP30Vyx4_bSJXo0tSi0OLKYYqc51_zeq3ozx7Q1TgjfBKP5A4lM8Vw6nj_VkQXiaCTSFacakWBQMsZuvn2DUfLA3Wso\" alt=\"Example for Copy List with Random Pointer problem\"\/><\/figure>\n\n\n\n<p>In this, we are given a linked list of 3 nodes x, y, and z as shown. We have to create 3 more nodes which are exact replicas of x,y, and z the only difference is that they have different addresses.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Hash-Map Approach<\/strong><\/h2>\n\n\n\n<p>The brute force approach is to first create n (n is the number of nodes in a linked list.) different nodes having the same values as the original linked list. Store each node address in a linked list as a key in the hash map and the value of those keys is the address of newly created nodes by you. <\/p>\n\n\n\n<p>After mapping iterate a loop and assign next and random values to the newly created nodes.<\/p>\n\n\n\n<p>Let\u2019s examine this approach through an example:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/2L-lEKXB9OAyrQNBKyHWxsfs4VmhYjxbTLsIbSglBPbUtYw98Gw_-kZEkAKiZnsGg0AHGegP4_Hi59q0Zq0CNA_z4OSEaXuQZHqgqYVxm34Tjs7tRM1vz4JcYTIxA-K31YWswsQ0-aLxgfVFWNjXLi4\" alt=\"Given Linked List List with hash map\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, make new nodes for each node and store the address of the previous node as a key in the map and the newly created node address as a value of that key.<\/li>\n\n\n\n<li>Iterate over the map and point the next pointer of the current value to the value of the key which is the next pointer to the current key.<\/li>\n\n\n\n<li>Iterate over the map and point the random pointer of the current value to the value of the key which is the random pointer to the current key.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/0kmV9ll2b8Lan-AUSQrHtflk5hGXCU6_iIDaUn9VDtQQmc19PvOHFscdW-ph_3oSr5b95Joi1qIa7eyPc6uoYpOsSr9hKMJhcgy-2QcaTXAI-_4uNbYtDixmhd5Bp9gQyMmGbiAVYIkrScGTTBMRz1Y\" alt=\"Resultant List\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Return the value of the first node of the liked list.<\/li>\n<\/ul>\n\n\n\n<p>The time complexity for the above code is O(n log(n) ). We are storing each node into the map which took O(n log(n) ) time. We are also iterating over the map whose time complexity is O(n), so the overall time complexity is O(n log(n) ). <\/p>\n\n\n\n<p>The space complexity for the above code is O(n) as we are storing each node on the map. (n is the number of nodes in a linked list.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Optimized Approach<\/strong><\/h2>\n\n\n\n<p>In the above approach, we are using an extra space which can be reduced if we do not use the hash map. Also storing values on the map takes extra time. In this approach, we will create a new node next to each node as a copy of the original nodes.&nbsp;<\/p>\n\n\n\n<p>Let\u2019s understand this approach step by step:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>First, iterate over the linked list.<\/li>\n\n\n\n<li>Make a new node at each iteration. Now point the new node to the next of the current node and the current node next as the new node.<\/li>\n\n\n\n<li>Now move to the next of new nodes.<\/li>\n\n\n\n<li>Repeat the same process till you reach the last node.<\/li>\n\n\n\n<li>Now again iterate the linked this and check the random pointer to the current pointer. Make Original-&gt;next-&gt;random = Original-&gt;random-&gt;next.<\/li>\n\n\n\n<li>Move to the next to the next of the original pointer and repeat the same process. Until you reach the null value.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/Z-Wf6RFEG27bz5-l_pu7GYdRIXItYae3XFTdbaY5Q0BrZxtTCAdIwLFEJsAK5AtLmCtLwtp_LkZurt4HvTYPzGe_xlfkw_1VzrqyJoJ7JpzTR63rNbdcjP3jNcfc0yC7B-kIFKAvIahZytbF3GU6Uc0\" alt=\"Example of optimized approach to copy linked list with random pointer\"\/><\/figure>\n\n\n\n<p>Let\u2019s examine the code for the given linked list.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C++ Code<\/strong><\/h3>\n\n\n\n<p>Below is the implementation of the optimized code in C++:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;C++&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">#include &lt;bits\/stdc++.h&gt;\nusing namespace std;\n\nclass node {\n    public:\n    int val;\n    node *next, *random;\n    node(int x) {\n        val = x;\n        next = random = NULL;\n    }\n};\n\nnode* new_list(node* head) {\n   \n\tif (head == NULL) {\n\t\treturn NULL;\n\t}\n\t\n\tnode* curr = head;\n\twhile (curr != NULL) {\n\t\tnode* temp = new node(curr-&gt;val);\n\t\ttemp-&gt;next = curr-&gt;next;\n\t\tcurr-&gt;next = temp;\n\t\tcurr = temp-&gt;next;\n\t}\n\t\n\tcurr = head;\n\twhile (curr != NULL) {\n\t\tif (curr-&gt;random != NULL) {\n\t\t\tcurr-&gt;next-&gt;random = curr-&gt;random-&gt;next;\n\t\t}\n\t\tcurr = curr-&gt;next-&gt;next;\n\t}\n\t\n\tcurr = head;\n\tnode* clonedhead = head-&gt;next;\n\tnode* clonedcurr = head-&gt;next;\n\twhile (clonedcurr-&gt;next != NULL) {\n\t\tcurr-&gt;next = curr-&gt;next-&gt;next;\n\t\tclonedcurr-&gt;next = clonedcurr-&gt;next-&gt;next;\n\t\tcurr = curr-&gt;next;\n\t\tclonedcurr = clonedcurr-&gt;next;\n\t}\n\tcurr-&gt;next = NULL;\n\tclonedcurr-&gt;next = NULL;\n\t\n\treturn clonedhead;\n}\n\nvoid printList(node* head)\n{\n\tcout &lt;&lt; head-&gt;val &lt;&lt; &quot;(&quot;;\n\tif(head-&gt;random) cout&lt;&lt;head-&gt;random-&gt;val;\n\telse cout&lt;&lt;&quot;NULL&quot;;\n\t\tcout &lt;&lt; &quot;)&quot;;\n\thead = head-&gt;next;\n\twhile (head != NULL) {\n\t\tcout &lt;&lt; &quot; -&gt; &quot; &lt;&lt; head-&gt;val &lt;&lt; &quot;(&quot;;\n\t\tif(head-&gt;random) cout&lt;&lt; head-&gt;random-&gt;val; \n\t\telse cout&lt;&lt;&quot;NULL&quot;;\n\t\tcout&lt;&lt; &quot;)&quot;;\n\t\thead = head-&gt;next;\n\t}\n\tcout &lt;&lt; endl;\n}\n\nint main()\n{\n\t\/\/ Creating a linked list with a random pointer\n\tnode* head = new node(1);\n\thead-&gt;next = new node(2);\n\thead-&gt;next-&gt;next = new node(3);\n\n    head-&gt;random = head-&gt;next-&gt;next;\n    head-&gt;next-&gt;random = head;\n\n\t\/\/ the original list\n\tcout &lt;&lt; &quot;Original linked list: &quot;;\n\tprintList(head);\n    \n\tnode* sol = new_list(head);\n\t\n\tcout &lt;&lt; &quot;Cloned linked list: &quot;;\n\tprintList(sol);\n\t\n\treturn 0;\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Java Code<\/strong><\/h3>\n\n\n\n<p>Here is the solution in Java:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Java&quot;,&quot;modeName&quot;:&quot;java&quot;}\">import java.util.HashMap;\n\nclass Node {\n    public int val;\n    public Node next, random;\n\n    public Node(int x) {\n        val = x;\n        next = random = null;\n    }\n}\n\npublic class CopyListWithRandomPointer {\n\n    public Node copyRandomList(Node head) {\n        if (head == null) return null;\n\n        Node curr = head;\n\n        \/\/ Create a new node for each existing node and insert it after the original node\n        while (curr != null) {\n            Node temp = new Node(curr.val);\n            temp.next = curr.next;\n            curr.next = temp;\n            curr = temp.next;\n        }\n\n        curr = head;\n\n        \/\/ Assign random pointers for the new nodes\n        while (curr != null) {\n            if (curr.random != null)\n                curr.next.random = curr.random.next;\n            curr = curr.next.next;\n        }\n\n        \/\/ Separate the original and cloned nodes\n        curr = head;\n        Node clonedHead = head.next;\n        Node clonedCurr = head.next;\n\n        while (clonedCurr.next != null) {\n            curr.next = curr.next.next;\n            clonedCurr.next = clonedCurr.next.next;\n            curr = curr.next;\n            clonedCurr = clonedCurr.next;\n        }\n\n        curr.next = null;\n        clonedCurr.next = null;\n\n        return clonedHead;\n    }\n\n    public static void printList(Node head) {\n        Node current = head;\n        while (current != null) {\n            System.out.print(current.val + &quot;(&quot; + (current.random != null ? current.random.val : &quot;NULL&quot;) + &quot;)&quot; + &quot; -&gt; &quot;);\n            current = current.next;\n        }\n        System.out.println(&quot;NULL&quot;);\n    }\n\n    public static void main(String[] args) {\n        CopyListWithRandomPointer solution = new CopyListWithRandomPointer();\n\n        Node head = new Node(1);\n        head.next = new Node(2);\n        head.next.next = new Node(3);\n\n        head.random = head.next.next;\n        head.next.random = head;\n\n        System.out.print(&quot;Original linked list: &quot;);\n        printList(head);\n\n        Node sol = solution.copyRandomList(head);\n\n        System.out.print(&quot;Cloned linked list: &quot;);\n        printList(sol);\n    }\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Python Code<\/strong><\/h3>\n\n\n\n<p>We can also implement it in Python to copy the list with a random pointer:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text\/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}\">class Node:\n    def __init__(self, x):\n        self.val = x\n        self.next = None\n        self.random = None\n\ndef copyRandomList(head: 'Node') -&gt; 'Node':\n    if head is None:\n        return None\n\n    curr = head\n\n    # Create a new node for each existing node and insert it after the original node\n    while curr:\n        temp = Node(curr.val)\n        temp.next = curr.next\n        curr.next = temp\n        curr = temp.next\n\n    curr = head\n\n    # Assign random pointers for the new nodes\n    while curr:\n        if curr.random:\n            curr.next.random = curr.random.next\n        curr = curr.next.next\n\n    # Separate the original and cloned nodes\n    curr = head\n    cloned_head = head.next\n    cloned_curr = head.next\n\n    while cloned_curr.next:\n        curr.next = curr.next.next\n        cloned_curr.next = cloned_curr.next.next\n        curr = curr.next\n        cloned_curr = cloned_curr.next\n\n    curr.next = None\n    cloned_curr.next = None\n\n    return cloned_head\n\ndef print_list(head: 'Node'):\n    current = head\n    while current:\n        print(f&quot;{current.val}({current.random.val if current.random else 'NULL'}) -&gt;&quot;, end=&quot; &quot;)\n        current = current.next\n    print(&quot;NULL&quot;)\n\nif __name__ == &quot;__main__&quot;:\n    # Creating a linked list with random pointer\n    head = Node(1)\n    head.next = Node(2)\n    head.next.next = Node(3)\n\n    head.random = head.next.next\n    head.next.random = head\n\n    # the original list\n    print(&quot;Original linked list: &quot;, end=&quot;&quot;)\n    print_list(head)\n\n    sol = copyRandomList(head)\n\n    print(&quot;Cloned linked list: &quot;, end=&quot;&quot;)\n    print_list(sol)<\/pre><\/div>\n\n\n\n<p><strong>Output:<\/strong>&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-text-color has-background has-link-color wp-elements-99bc8ae4d1a3c0a197a7b8ba9f1cf287\" style=\"background-color:#fedcba\"><code> Original linked list: 1(3) -&gt; 2(1) -&gt; 3(NULL)\n Cloned linked list: 1(3) -&gt; 2(1) -&gt; 3(NULL)<\/code><\/pre>\n\n\n\n<p>The time complexity is now reduced to O(n) as we are just iterating over the linked list two times. The Space Complexity is reduced to O(1) as we are not using any extra space.<\/p>\n\n\n\n<p>We can compare the difference the optimized approach makes to copy the list with a random pointer:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Approach<\/th><th>&nbsp;Time Complexity<\/th><th class=\"has-text-align-center\" data-align=\"center\">&nbsp;Space Complexity<\/th><th class=\"has-text-align-center\" data-align=\"center\"> Description<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Brute Force&nbsp;<\/td><td>O(n log(n))<\/td><td class=\"has-text-align-center\" data-align=\"center\">O(n)<\/td><td class=\"has-text-align-center\" data-align=\"center\">We are storing the values into the map which requires log(n) time complexity.<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Optimized Approach<\/td><td>O(n)<\/td><td class=\"has-text-align-center\" data-align=\"center\">O(1)<\/td><td class=\"has-text-align-center\" data-align=\"center\">We are just iterating the linked list two times which reduces the time complexity from O(n log(n)) to O(n).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>This article helps us understand various approaches to solving the <a href=\"https:\/\/leetcode.com\/problems\/copy-list-with-random-pointer\/description\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">leetcode problem<\/a> for copying a list with a random pointer. There are more <a href=\"https:\/\/favtutor.com\/articles\/category\/data-structures-algorithms\/\">leetcode solutions<\/a> to master Data Structures and Algorithms.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to solve the leetcode problem to Copy a List with a Random Pointer with programs in C++, Java, and Python.<\/p>\n","protected":false},"author":14,"featured_media":1972,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jnews-multi-image_gallery":[],"jnews_single_post":null,"jnews_primary_category":{"id":"","hide":""},"footnotes":""},"categories":[7],"tags":[31,14,15,32],"class_list":["post-1967","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-structures-algorithms","tag-c","tag-dsa","tag-leetcode","tag-python"],"_links":{"self":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1967","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/comments?post=1967"}],"version-history":[{"count":4,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1967\/revisions"}],"predecessor-version":[{"id":2401,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1967\/revisions\/2401"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media\/1972"}],"wp:attachment":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media?parent=1967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/categories?post=1967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/tags?post=1967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}