- Related Questions & Answers
- Print reverse of a Linked List without extra space and modification in C Program.
- C++ Program to Implement Sorted Singly Linked List
- C++ Program to Implement Sorted Circularly Singly Linked List
- Find middle of singly linked list Recursively in C++
- Find a pair with given sum in a Balanced BST in Java
- Sum of the nodes of a Singly Linked List in C Program
- Find a pair with the given difference in C++
- Find the common nodes in two singly linked list in C++
- Check if a pair with given product exists in Linked list in C++
- Convert singly linked list into circular linked list in C++
- Convert singly linked list into XOR linked list in C++
- Find the closest pair from two sorted arrays in c++
- Find minimum and maximum elements in singly Circular Linked List in C++
- Python Program for Find the closest pair from two sorted arrays
- Binary Search on Singly Linked List in C++

- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who

With respect of a given sorted singly linked list and a value x, our task is to determinepair whose sum is equal to x. Here we are not permitted to use any extra space and expected time complexity be O(n).

head = 4-->7-->8-->9-->10-->11-->12 , x=19

(7, 12), (8, 11), (9, 10)

According to a simple solution for this problem, we take each element one by one and visit the rest list in forward direction to determine second element whose sum is equal to given value x. Here, time complexity for this method will be O(n^2).

We discuss an efficient solution for this problem in following topic.

**Find pair in doubly linked list** − The method is explained in below.

According to a simple approach for this problem, we pick each node one by one and determine second element whose sum is equal to x in the rest list by visiting in forward direction.Here, time complexity for this problem will be O(n^2) , where n is total number of nodes in doubly linked list.

An efficient solution for this problem is discussed. Here are the steps of the algorithm −

We initialize two pointer variables to determine the candidate elements in the sorted doubly linked list.

We initialize first1 with start of doubly linked list that means, first1=head and initialize second1 with last node of doubly linked list that means, second1=last_node.

Now we initialize first and second pointers as first and last nodes. In this case we don’t have random access, so to determine second pointer, we visit the list to initialize second1.

It has been seen that if current sum of first1 and second1 is smaller than x, then we move first1 in forward direction. Otherwise if current sum of first1 and second1 is greater than x, then we move second1 in backward direction.

Finally, loop termination conditions are also different from arrays. In this case, the loop ends when either of two pointers become NULL, or they cross each other (second1->next = first1), or they become same (first1 == second1).

**XOR Linked list** − With respect of singly linked list, we can visit list only in forward direction. We implement XOR concept to convert a singly linked list to doubly linked list.Following are steps −

At first we need to convert our singly linked list into doubly linked list. In this case, we are given singly linked list structure node which have only next pointernot prev pointer, as a result of this,to convert our singly linked list into doubly linked list we implementmemory efficient doubly linked list ( XOR linked list ).

With respect of XOR linked list, each next pointer of singly linked list containsXOR of next and prev pointer.

Here, after converting singly linked list into doubly linked list we initialize two pointers variables to determine the candidate elements in the sorted doubly linked list. We initialize first1 with start of doubly linked list i.e; first1 = head and initialize second1 with last node of doubly linked list i.e; second1 = last_node.

At present we don’t have random access, so for initializing pointer, we visitthe list until last node and assign last node to second1.

It has been seen that if current sum of first1 and second1 is smaller than x, then we move first1 in forward direction. Otherwise if current sum of first1 and second1 isgreater than x, then we move second1 in backward direction.

Finally, loop termination conditions are also different from arrays. In this case, the loop ends when either of two pointers become NULL, or they cross each other (second1->next = first1), or they become same (first1 == second1).

// C++ program to find pair with given sum in a singly // linked list in O(n) time and no extra space. #include<bits/stdc++.h> using namespace std; /* Shows Link list node */ struct Node1{ int data1; /* also contains XOR of next and previous node after conversion*/ struct Node1* next1; }; /* With respect of a given reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void insert(struct Node1** head_ref1, int new_data1){ /*Used to allocate node */ struct Node1* new_node1 = (struct Node1*) malloc(sizeof(struct Node1)); /* Used to put in the data */ new_node1->data1 = new_data1; /* Shows link the old list off the new node */ new_node1->next1 = (*head_ref1); /* Used to move the head to point to the new node */ (*head_ref1) = new_node1; } /* Here returns XORed value of the node addresses */ struct Node1* XOR (struct Node1 *p, struct Node1 *q){ return (struct Node1*) ((uintptr_t) (p) ^ (uintptr_t) (q)); } // Shows utility function to convert singly linked list // into XOR doubly linked list void convert(struct Node1 *head1){ // At first we store address of next node in it // then take XOR of next node and previous node // and store it in next pointer struct Node1 *next_node1; // Here prev1 node stores the address of previously // visited node struct Node1 *prev1 = NULL; // Used to traverse list and store xor of address of // next_node1 and prev1 node in next pointer of node while (head1 != NULL){ // Shows address of next node next_node1 = head1->next1; // Shows xor of next_node1 and prev1 node head1->next1 = XOR(next_node1, prev1); // Used to update previous node prev1 = head1; // Used to move head1 forward head1 = next_node1; } } // Shows function to determine pair whose sum is equal to // given value x1 void pairSum(struct Node1 *head1, int x1){ // Used to initialize first1 struct Node1 *first1 = head1; // next_node1 and prev1 node to compute xor again // and determine next and prev node while moving forward // and backward direction from both the corners struct Node1 *next_node1 = NULL, *prev1 = NULL; // Used to traverse list to initialize second pointer // here we need to move in forward direction so to // compute next address we have to take xor // with prev pointer because (p^q)^q = p struct Node1 *second1 = head1; while (second1->next1 != prev1){ struct Node1 *temp1 = second1; second1 = XOR(second1->next1, prev1); prev1 = temp1; } // At present traverse from both the corners next_node1 = NULL; prev1 = NULL; // Now if we want to move forward then we must // know the prev1 address to compute next node // and if we want to move backward then we must // know the next_node1 address to calculate prev1 node bool flag1 = false; while (first1 != NULL && second1 != NULL && first1 != second1 && first1 != next_node1){ if ((first1->data1 + second1->data1)==x1){ cout << "(" << first1->data1 << ","<< second1->data1 << ")" << endl; flag1 = true; // Used to move first in forward struct Node1 *temp1 = first1; first1 = XOR(first1->next1,prev1); prev1 = temp1; // Used to move second in backward temp1 = second1; second1 = XOR(second1->next1, next_node1); next_node1 = temp1; } else { if ((first1->data1 + second1->data1) < x1){ // Used to move first in forward struct Node1 *temp1 = first1; first1 = XOR(first1->next1,prev1); prev1 = temp1; } else { // Used to move second in backward struct Node1 *temp1 = second1; second1 = XOR(second1->next1, next_node1); next_node1 = temp1; } } } if (flag1 == false) cout << "No pair found" << endl; } // Driver program to run the case int main(){ /* Begin with the empty list */ struct Node1* head1 = NULL; // int x1 = 17; int x1 = 19; /* Use insert() to construct below list 3-->6-->7-->8-->9-->10-->11 */ /* insert(&head1, 11); insert(&head1, 10); insert(&head1, 9); insert(&head1, 8); insert(&head1, 7); insert(&head1, 6); insert(&head1, 3); */ /* Use insert() to construct below list 4-->7-->8-->9-->10-->11-->12 */ insert(&head1, 12); insert(&head1, 11); insert(&head1, 10); insert(&head1, 9); insert(&head1, 8); insert(&head1, 7); insert(&head1, 4); // Used to convert singly linked list into XOR doubly // linked list convert(head1); pairSum(head1,x1); return 0; }

(7,12) (8,11) (9,10)

Advertisements