Add two numbers represented by Linked List without any extra space
Given two numbers represented by two linked lists, write a function that returns sum list. The sum list is linked list representation of addition of two input numbers. Expected Space Complexity O(1).
Examples:
Input:
L1 = 5 -> 6 -> 3 -> NULL
L2 = 8 -> 4 -> 2 -> NULL
Output: 1 -> 4 -> 0 -> 5 -> NULLInput:
L1 = 1 -> 0 -> 0 -> NULL
L2 = 9 -> 1 -> NULL
Output: 1 -> 9 -> 1 -> NULL
Approach: We have discussed a solution here where we used recursion to reach to the least significant number in the lists, but due to the involvement of the stack, the space complexity of the solution becomes O(N)
Here the target is to do the sum inplace, and return the modified sum list.
The idea is to first reverse both the linked list, so new head of the list points to least significant number and we can start adding as described here and instead of creating a new list, we modify the existing one and return the head of modified list.
Following are the steps:
- Reverse List L1.
- Reverse List L2.
- Add the nodes of both the lists iteratively.
- Reverse the resultant list and return its head.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <iostream> using namespace std; class LinkedList; // Node class for the linked list class Node { int data; Node* next; friend LinkedList; public : Node(); Node( int x); }; Node::Node() { data = 0; next = NULL; } // Function to initialise // a node with value x Node::Node( int x) { data = x; next = NULL; } // Linkedlist class with helper functions class LinkedList { public : Node* head; LinkedList(); void insert( int x); void reverse(); void traverse(); void sum(LinkedList*); }; LinkedList::LinkedList() { head = NULL; } // Function to insert a node at // the head of the list void LinkedList::insert( int x) { Node* node = new Node(); node->data = x; if (head == NULL) head = node; else { node->next = head; head = node; } } // Function to reverse the linked list void LinkedList::reverse() { Node *prev = NULL, *curr = head; while (curr) { Node* temp = curr->next; curr->next = prev; prev = curr; curr = temp; } head = prev; } // Function to traverse and print the list void LinkedList::traverse() { Node* temp = head; while (temp) { cout << temp->data << " -> " ; temp = temp->next; } cout << "NULL" ; } // Function to add two numbers // represented as linked lists void LinkedList::sum(LinkedList* l2) { reverse(); l2->reverse(); Node *start1 = head, *start2 = l2->head; Node* prev = NULL; int carry = 0; // While both lists exist while (start1 && start2) { // Current sum int temp = start1->data + start2->data + carry; // Handle carry start1->data = temp % 10; carry = temp / 10; prev = start1; // Get to next nodes start1 = start1->next; start2 = start2->next; } // If there are remaining digits // in any one of the lists if (start1 || start2) { if (start2) prev->next = start2; start1 = prev->next; // While first list has digits remaining while (start1) { int temp = start1->data + carry; start1->data = temp % 10; carry = temp / 10; prev = start1; start1 = start1->next; } } // If a new node needs to be // created due to carry if (carry > 0) { prev->next = new Node(carry); } // Reverse the resultant list reverse(); } // Driver code int main() { // Create first list LinkedList* l1 = new LinkedList(); l1->insert(3); l1->insert(6); l1->insert(5); // Create second list LinkedList* l2 = new LinkedList(); l2->insert(2); l2->insert(4); l2->insert(8); // Add the lists l1->sum(l2); // Print the resultant list l1->traverse(); return 0; } |
Java
// Java implementation of the approach import java.util.*; class Node { int data; Node next; // constructor Node( int d) { data = d; next = null ; } } // Node closes class LinkedList { Node head; // Helper function to traverse void traverse(Node head) { while (head != null ) { System.out.print(head.data + "->" ); head = head.next; } } // Helper function to insert data in linked list void insert( int x) { Node temp = new Node(x); if (head == null ) head = temp; else { temp.next = head; head = temp; } } // Helper function to reverse the list public static Node reverse(Node head) { if (head == null || head.next == null ) return head; Node prev = null ; Node curr = head; while (curr != null ) { Node temp = curr.next; curr.next = prev; prev = curr; curr = temp; } head = prev; return head; } // Function to add two lists public static Node sum(Node l1, Node l2) { if (l2 == null ) return l1; if (l1 == null ) return l2; // reverse l1 list l1 = reverse(l1); // reverse l2 list l2 = reverse(l2); // storing head whose reverse is to be returned // This is where which will be final node Node head = l1; Node prev = null ; int c = 0 ,sum; while (l1 != null && l2 != null ) { sum = c + l1.data + l2.data; l1.data = sum % 10 ; c = sum / 10 ; prev = l1; l1 = l1.next; l2 = l2.next; } if (l1 != null ||l2 != null ) { if (l2 != null ) prev.next = l2; l1 = prev.next; while (l1 != null ) { sum = c + l1.data; l1.data = sum % 10 ; c = sum / 10 ; prev = l1; l1 = l1.next; } } if (c > 0 ) prev.next = new Node(c); return reverse(head); } // Driver Code public static void main(String[] args) { LinkedList l1 = new LinkedList(); l1.insert( 3 ); l1.insert( 6 ); l1.insert( 5 ); LinkedList l2 = new LinkedList(); l2.insert( 2 ); l2.insert( 4 ); l2.insert( 8 ); LinkedList l3 = new LinkedList(); Node head = sum(l1.head, l2.head); l3.traverse(head); System.out.print( "Null" ); } } // This code is contributed // by Devarshi Singh |
Python3
# Python3 implementation of the approach # Linked List Node class Node: def __init__( self , data): self .data = data self . next = None # Handle list operations class LinkedList: def __init__( self ): self .head = None # Method to traverse list and # return it in a format def traverse( self ): linkedListStr = "" temp = self .head while temp: linkedListStr + = str (temp.data) + " -> " temp = temp. next return linkedListStr + "NULL" # Method to insert data in linked list def insert( self , data): newNode = Node(data) if self .head is None : self .head = newNode else : newNode. next = self .head self .head = newNode # Helper function to reverse the list def reverse(Head): if (Head is None and Head. next is None ): return Head prev = None curr = Head while curr: temp = curr. next curr. next = prev prev = curr curr = temp Head = prev return Head # Function to add two lists def listSum(l1, l2): if l1 is None : return l1 if l2 is None : return l2 # Reverse first list l1 = reverse(l1) # Reverse second list l2 = reverse(l2) # Storing head whose reverse # is to be returned This is # where which will be final node head = l1 prev = None c = 0 sum = 0 while l1 is not None and l2 is not None : sum = c + l1.data + l2.data l1.data = sum % 10 c = int ( sum / 10 ) prev = l1 l1 = l1. next l2 = l2. next if l1 is not None or l2 is not None : if l2 is not None : prev. next = l2 l1 = prev. next while l1 is not None : sum = c + l1.data l1.data = sum % 10 c = int ( sum / 10 ) prev = l1 l1 = l1. next if c > 0 : prev. next = Node(c) return reverse(head) # Driver code linkedList1 = LinkedList() linkedList1.insert( 3 ) linkedList1.insert( 6 ) linkedList1.insert( 5 ) linkedList2 = LinkedList() linkedList2.insert( 2 ) linkedList2.insert( 4 ) linkedList2.insert( 8 ) linkedList3 = LinkedList() linkedList3.head = listSum(linkedList1.head, linkedList2.head) print (linkedList3.traverse()) # This code is contributed by Debidutta Rath |
C#
// C# implementation of the above approach using System; public class Node { public int data; public Node next; // constructor public Node( int d) { data = d; next = null ; } } // Node closes public class LinkedList { Node head; // Helper function to traverse void traverse(Node head) { while (head != null ) { Console.Write(head.data + "->" ); head = head.next; } } // Helper function to insert data in linked list void insert( int x) { Node temp = new Node(x); if (head == null ) head = temp; else { temp.next = head; head = temp; } } // Helper function to reverse the list public static Node reverse(Node head) { if (head == null || head.next == null ) return head; Node prev = null ; Node curr = head; while (curr != null ) { Node temp = curr.next; curr.next = prev; prev = curr; curr = temp; } head = prev; return head; } // Function to add two lists public static Node sum(Node l1, Node l2) { if (l2 == null ) return l1; if (l1 == null ) return l2; // reverse l1 list l1 = reverse(l1); // reverse l2 list l2 = reverse(l2); // storing head whose reverse is // to be returned. This is where // which will be final node Node head = l1; Node prev = null ; int c = 0,sum; while (l1 != null && l2 != null ) { sum = c + l1.data + l2.data; l1.data = sum % 10; c = sum / 10; prev = l1; l1 = l1.next; l2 = l2.next; } if (l1 != null ||l2 != null ) { if (l2 != null ) prev.next = l2; l1 = prev.next; while (l1 != null ) { sum = c + l1.data; l1.data = sum % 10; c = sum / 10; prev = l1; l1 = l1.next; } } if (c > 0) prev.next = new Node(c); return reverse(head); } // Driver Code public static void Main(String[] args) { LinkedList l1 = new LinkedList(); l1.insert(3); l1.insert(6); l1.insert(5); LinkedList l2 = new LinkedList(); l2.insert(2); l2.insert(4); l2.insert(8); LinkedList l3 = new LinkedList(); Node head = sum(l1.head, l2.head); l3.traverse(head); Console.Write( "Null" ); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // Javascript implementation of the approach class Node { constructor(val) { this .data = val; this .next = null ; } } // Linkedlist class with helper functions class LinkedList { constructor() { this .head = null ; } // Function to insert a node at // the head of the list insert(x) { var node = new Node(); node.data = x; if ( this .head == null ) this .head = node; else { node.next = this .head; this .head = node; } } // Function to reverse the linked list reverse() { var prev = null , curr = this .head; while (curr) { var temp = curr.next; curr.next = prev; prev = curr; curr = temp; } this .head = prev; } // Function to traverse and print the list traverse() { var temp = this .head; while (temp) { document.write( temp.data + " -> " ); temp = temp.next; } document.write( "null" ); } // Function to add two numbers // represented as linked lists sum(l2) { this .reverse(); l2.reverse(); var start1 = this .head, start2 = l2.head; var prev = null ; var carry = 0; // While both lists exist while (start1 && start2) { // Current sum var temp = start1.data + start2.data + carry; // Handle carry start1.data = temp % 10; carry = parseInt(temp / 10); prev = start1; // Get to next nodes start1 = start1.next; start2 = start2.next; } // If there are remaining digits // in any one of the lists if (start1 || start2) { if (start2) prev.next = start2; start1 = prev.next; // While first list has digits remaining while (start1) { var temp = start1.data + carry; start1.data = temp % 10; carry = parseInt(temp / 10); prev = start1; start1 = start1.next; } } // If a new node needs to be // created due to carry if (carry > 0) { prev.next = new Node(carry); } // Reverse the resultant list this .reverse(); } }; // Driver code // Create first list var l1 = new LinkedList(); l1.insert(3); l1.insert(6); l1.insert(5); // Create second list var l2 = new LinkedList(); l2.insert(2); l2.insert(4); l2.insert(8); // Add the lists l1.sum(l2); // Print the resultant list l1.traverse(); // This code is contributed by itsok. </script> |
1 -> 4 -> 0 -> 5 -> NULL
Time Complexity: O(max(m, n)) where m and n are number of nodes in list l1 and list l2 respectively.
Space Complexity: O(1)
Please Login to comment...