Articles by FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
Articles by FavTutor
No Result
View All Result
Home Data Structures and Algorithms

Copy List with Random Pointer Problem (with Solution)

Mansi Agarwal by Mansi Agarwal
March 14, 2024
Reading Time: 9 mins read
Copy List With Random Pointer Problem
Follow us on Google News   Subscribe to our newsletter

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.

Copy List with Random Pointer problem

Before moving forward, remember that there are two different methods to copy a node in a linked list.

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.

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. 

Let’s look at the example for more clarity:

Example for Copy List with Random Pointer problem

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.

Hash-Map Approach

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.

After mapping iterate a loop and assign next and random values to the newly created nodes.

Let’s examine this approach through an example:

Given Linked List List with hash map
  • 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.
  • 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.
  • 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.
Resultant List
  • Return the value of the first node of the liked list.

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) ).

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.)

Optimized Approach

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. 

Let’s understand this approach step by step:

  1. First, iterate over the linked list.
  2. 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.
  3. Now move to the next of new nodes.
  4. Repeat the same process till you reach the last node.
  5. Now again iterate the linked this and check the random pointer to the current pointer. Make Original->next->random = Original->random->next.
  6. Move to the next to the next of the original pointer and repeat the same process. Until you reach the null value.
Example of optimized approach to copy linked list with random pointer

Let’s examine the code for the given linked list.

C++ Code

Below is the implementation of the optimized code in C++:

#include <bits/stdc++.h>
using namespace std;

class node {
    public:
    int val;
    node *next, *random;
    node(int x) {
        val = x;
        next = random = NULL;
    }
};

node* new_list(node* head) {
   
	if (head == NULL) {
		return NULL;
	}
	
	node* curr = head;
	while (curr != NULL) {
		node* temp = new node(curr->val);
		temp->next = curr->next;
		curr->next = temp;
		curr = temp->next;
	}
	
	curr = head;
	while (curr != NULL) {
		if (curr->random != NULL) {
			curr->next->random = curr->random->next;
		}
		curr = curr->next->next;
	}
	
	curr = head;
	node* clonedhead = head->next;
	node* clonedcurr = head->next;
	while (clonedcurr->next != NULL) {
		curr->next = curr->next->next;
		clonedcurr->next = clonedcurr->next->next;
		curr = curr->next;
		clonedcurr = clonedcurr->next;
	}
	curr->next = NULL;
	clonedcurr->next = NULL;
	
	return clonedhead;
}

void printList(node* head)
{
	cout << head->val << "(";
	if(head->random) cout<<head->random->val;
	else cout<<"NULL";
		cout << ")";
	head = head->next;
	while (head != NULL) {
		cout << " -> " << head->val << "(";
		if(head->random) cout<< head->random->val; 
		else cout<<"NULL";
		cout<< ")";
		head = head->next;
	}
	cout << endl;
}

int main()
{
	// Creating a linked list with a random pointer
	node* head = new node(1);
	head->next = new node(2);
	head->next->next = new node(3);

    head->random = head->next->next;
    head->next->random = head;

	// the original list
	cout << "Original linked list: ";
	printList(head);
    
	node* sol = new_list(head);
	
	cout << "Cloned linked list: ";
	printList(sol);
	
	return 0;
}

Java Code

Here is the solution in Java:

import java.util.HashMap;

class Node {
    public int val;
    public Node next, random;

    public Node(int x) {
        val = x;
        next = random = null;
    }
}

public class CopyListWithRandomPointer {

    public Node copyRandomList(Node head) {
        if (head == null) return null;

        Node curr = head;

        // Create a new node for each existing node and insert it after the original node
        while (curr != null) {
            Node temp = new Node(curr.val);
            temp.next = curr.next;
            curr.next = temp;
            curr = temp.next;
        }

        curr = head;

        // Assign random pointers for the new nodes
        while (curr != null) {
            if (curr.random != null)
                curr.next.random = curr.random.next;
            curr = curr.next.next;
        }

        // Separate the original and cloned nodes
        curr = head;
        Node clonedHead = head.next;
        Node clonedCurr = head.next;

        while (clonedCurr.next != null) {
            curr.next = curr.next.next;
            clonedCurr.next = clonedCurr.next.next;
            curr = curr.next;
            clonedCurr = clonedCurr.next;
        }

        curr.next = null;
        clonedCurr.next = null;

        return clonedHead;
    }

    public static void printList(Node head) {
        Node current = head;
        while (current != null) {
            System.out.print(current.val + "(" + (current.random != null ? current.random.val : "NULL") + ")" + " -> ");
            current = current.next;
        }
        System.out.println("NULL");
    }

    public static void main(String[] args) {
        CopyListWithRandomPointer solution = new CopyListWithRandomPointer();

        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);

        head.random = head.next.next;
        head.next.random = head;

        System.out.print("Original linked list: ");
        printList(head);

        Node sol = solution.copyRandomList(head);

        System.out.print("Cloned linked list: ");
        printList(sol);
    }
}

Python Code

We can also implement it in Python to copy the list with a random pointer:

class Node:
    def __init__(self, x):
        self.val = x
        self.next = None
        self.random = None

def copyRandomList(head: 'Node') -> 'Node':
    if head is None:
        return None

    curr = head

    # Create a new node for each existing node and insert it after the original node
    while curr:
        temp = Node(curr.val)
        temp.next = curr.next
        curr.next = temp
        curr = temp.next

    curr = head

    # Assign random pointers for the new nodes
    while curr:
        if curr.random:
            curr.next.random = curr.random.next
        curr = curr.next.next

    # Separate the original and cloned nodes
    curr = head
    cloned_head = head.next
    cloned_curr = head.next

    while cloned_curr.next:
        curr.next = curr.next.next
        cloned_curr.next = cloned_curr.next.next
        curr = curr.next
        cloned_curr = cloned_curr.next

    curr.next = None
    cloned_curr.next = None

    return cloned_head

def print_list(head: 'Node'):
    current = head
    while current:
        print(f"{current.val}({current.random.val if current.random else 'NULL'}) ->", end=" ")
        current = current.next
    print("NULL")

if __name__ == "__main__":
    # Creating a linked list with random pointer
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)

    head.random = head.next.next
    head.next.random = head

    # the original list
    print("Original linked list: ", end="")
    print_list(head)

    sol = copyRandomList(head)

    print("Cloned linked list: ", end="")
    print_list(sol)

Output: 

 Original linked list: 1(3) -> 2(1) -> 3(NULL)
 Cloned linked list: 1(3) -> 2(1) -> 3(NULL)

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.

We can compare the difference the optimized approach makes to copy the list with a random pointer:

Approach Time Complexity Space Complexity Description
Brute Force O(n log(n))O(n)We are storing the values into the map which requires log(n) time complexity.
Optimized ApproachO(n)O(1)We are just iterating the linked list two times which reduces the time complexity from O(n log(n)) to O(n).

Conclusion

This article helps us understand various approaches to solving the leetcode problem for copying a list with a random pointer. There are more leetcode solutions to master Data Structures and Algorithms.

ShareTweetShareSendSend
Mansi Agarwal

Mansi Agarwal

I am Mansi Agarwal, a final-year student at IIT BHU. I am very keen on competitive programming, with my primary area of interest being Data Structures & Algorithms. I have solved over 1000 LeetCode problems.

RelatedPosts

validate ip address

Validate IP Address Problem ( C++, JAVA, Python)

April 3, 2025
Shortest Palindrome Problem

Shortest Palindrome Problem ( C++, JAVA, Python)

April 4, 2025
Zigzag Conversion Problem

Zigzag Conversion Problem (C++, Java, Python)

April 4, 2025
Next Right Pointers In Each Node

Populating Next Right Pointers In Each Node (with code)

March 27, 2024
Coin Change II

Coin Change II Problem (C++, Java, Python)

April 7, 2025

About FavTutor

FavTutor is a trusted online tutoring service to connects students with expert tutors to provide guidance on Computer Science subjects like Java, Python, C, C++, SQL, Data Science, Statistics, etc.

Categories

  • AI News, Research & Latest Updates
  • Trending
  • Data Structures
  • Web Developement
  • Data Science

Important Subjects

  • Python Assignment Help
  • C++ Help
  • R Programming Help
  • Java Homework Help
  • Programming Help

Resources

  • About Us
  • Contact Us
  • Editorial Policy
  • Privacy Policy
  • Terms and Conditions

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.

No Result
View All Result
  • AI News
  • Data Structures
  • Web Developement
  • AI Code Generator
  • Student Help
  • Main Website

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.