Print all triplets with sum S in given sorted Linked List
Given a sorted singly linked list as list of N distinct nodes (no two nodes have the same data) and an integer S. The task is to find all distinct triplets in the list that sum up to given integer S.
Examples:
Input: list = 1->2->4->5->6->8->9, S = 15
Output: [(1, 5, 9), (1, 6, 8), (2, 4, 9), (2 ,5, 8), (4, 5, 6)]
Explanation: These are the only distinct triplets which have sum equal to S i.e 15. Note that (2, 4, 9) and (9, 4, 2) both triplets have sum 15 but they are not distinct as all the elements of the triplets are same.Input: list = 1->2->4->5->6->8->9, S = 17
Output: [(2, 6, 9), (4, 5, 8)]
Naive approach: Use three nested loop. Generate all triplets and find the distinct triplets having sum equal to S.
Time Complexity: O(N3)
Auxiliary Space: O(N3)
Efficient Approach: Use concept of hashing to efficiently solve the problem. Follow the steps mentioned below
- Create a hash array to store the scanned node data.
- Insert head node value into the hash array.
- Now start traversing the linked list using nested loops, and in each iteration:
- Subtract the data of both the nodes from the given integer ‘S’ to find the value which makes the triplet.
- Now find that value in the hash array.
- If that value is present in the hash array(i. e. triplet is found), then store the triplet in a list as a possible answer.
- Return the list.
Below is the implementation of the above approach:
C++
// C++ code to find // all distinct triplets having sum S #include <bits/stdc++.h> using namespace std; // Structure of node of singly linked list struct Node { int data; Node* next; Node( int x) { data = x; next = NULL; } }; // Inserting new node // at the beginning of the linked list void push( struct Node** head_ref, int new_data) { // Create a new node with the given data. struct Node* new_node = new Node(new_data); // Make the new node point to the head. new_node->next = (*head_ref); // Make the new node as the head node. (*head_ref) = new_node; } // Function to print triplets // in a sorted singly linked list // whose sum is equal to given value 'S' vector<vector< int >> printTriplets( struct Node* head, int S) { // Declare unordered map // to store the scanned value unordered_map< int , bool > mp; // Vector to store the triplets vector<vector< int >> v; // Declare two pointers 'p' and 'q' // for traversing singly linked list struct Node* p; struct Node* q; // Insert 1st node data into map // and start traversing from next node mp[head->data] = true ; // Outer loop terminates // when last node reached for (p = head->next; p->next != NULL; p = p->next) { // Inner loop terminates // when second pointer become NULL for (q = p->next; q != NULL; q = q->next) { // Temporary vector // to store the current triplet vector< int > temp; int second = p->data; int third = q->data; // find the number required // to make triplet by subtracting // node1 and node2 data from S // and store it. int first = S - second - third; // Search if that value // is present in the map or not if (mp.find(first) != mp.end()) { // If 'first' is present // in map, make a triplet of // first,second & third temp.push_back(mp.find(first)->first); temp.push_back(second); temp.push_back(third); // Push current triplet // stored in 'temp' to // vector 'v' v.push_back(temp); } } // Insert current node data into map mp[p->data] = true ; } // Return a vector of triplets. return v; } // Driver code int main() { int S = 15; // Create an empty singly linked list struct Node* head = NULL; vector<vector< int > > ans; // Insert values in sorted order push(&head, 9); push(&head, 8); push(&head, 6); push(&head, 5); push(&head, 4); push(&head, 2); push(&head, 1); // Call printTriplets function // to find all triplets in // the linked list ans = printTriplets(head, S); // Sort and display // all possible triplets sort(ans.begin(), ans.end()); for ( int i = 0; i < ans.size(); i++) { for ( int j = 0; j < ans[i].size(); j++) { cout << ans[i][j] << " " ; } cout << "\n" ; } return 0; } |
Java
// Java code to find // all distinct triplets having sum S import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; class GFG { // Structure of node of singly linked list static class Node { int data; Node next; public Node( int x) { data = x; next = null ; } }; // Function to print triplets // in a sorted singly linked list // whose sum is equal to given value 'S' public static ArrayList<ArrayList<Integer>> printTriplets(Node head, int S) { // Declare unordered map // to store the scanned value HashMap<Integer, Boolean> mp = new HashMap<Integer, Boolean>(); // Vector to store the triplets ArrayList<ArrayList<Integer>> v = new ArrayList<ArrayList<Integer>>(); // Declare two pointers 'p' and 'q' // for traversing singly linked list Node p; Node q; // Insert 1st node data into map // and start traversing from next node mp.put(head.data, true ); // Outer loop terminates // when last node reached for (p = head.next; p.next != null ; p = p.next) { // Inner loop terminates // when second pointer become null for (q = p.next; q != null ; q = q.next) { // Temporary vector // to store the current triplet ArrayList<Integer> temp = new ArrayList<Integer>(); int second = p.data; int third = q.data; // find the number required // to make triplet by subtracting // node1 and node2 data from S // and store it. int first = S - second - third; // Search if that value // is present in the map or not if (mp.containsKey(first)) { // If 'first' is present // in map, make a triplet of // first,second & third temp.add(first); temp.add(second); temp.add(third); // Push current triplet // stored in 'temp' to // vector 'v' v.add(temp); } } // Insert current node data into map mp.put(p.data, true ); } // Return a vector of triplets. return v; } // Driver code public static void main(String args[]) { int S = 15 ; // Create an empty singly linked list Node head = null ; ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>(); // Insert values in sorted order head = new Node( 9 ); head.next = new Node( 8 ); head.next.next = new Node( 6 ); head.next.next.next = new Node( 5 ); head.next.next.next.next = new Node( 4 ); head.next.next.next.next.next = new Node( 2 ); head.next.next.next.next.next.next = new Node( 1 ); // Call printTriplets function // to find all triplets in // the linked list ans = printTriplets(head, S); // Sort and display // all possible triplets for (ArrayList<Integer> x : ans) { Collections.sort(x); } Collections.sort(ans, new Comparator<ArrayList<Integer>>() { @Override public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) { return o2.get( 0 ) - (o1.get( 0 )); } }); Collections.reverse(ans); for ( int i = 0 ; i < ans.size(); i++) { for ( int j = 0 ; j < ans.get(i).size(); j++) { System.out.print(ans.get(i).get(j) + " " ); } System.out.println( "" ); } } } // This code is contributed by gfgking. |
Javascript
<script> // JavaScript Program to implement // the above approach // Structure of node of singly linked list class Node { constructor(x) { this .data = x; this .next = null ; } }; // Function to print triplets // in a sorted singly linked list // whose sum is equal to given value 'S' function printTriplets(head, S) { // Declare unordered map // to store the scanned value let mp = new Map(); // Vector to store the triplets let v = []; // Declare two pointers 'p' and 'q' // for traversing singly linked list let p; let q; // Insert 1st node data into map // and start traversing from next node mp.set(head.data, true ); // Outer loop terminates // when last node reached for (p = head.next; p.next != null ; p = p.next) { // Inner loop terminates // when second pointer become null for (q = p.next; q != null ; q = q.next) { // Temporary vector // to store the current triplet let temp = []; let second = p.data; let third = q.data; // find the number required // to make triplet by subtracting // node1 and node2 data from S // and store it. let first = S - second - third; // Search if that value // is present in the map or not if (mp.has(first)) { // If 'first' is present // in map, make a triplet of // first,second & third temp.push(first); temp.push(second); temp.push(third); // Push current triplet // stored in 'temp' to // vector 'v' v.push(temp); } } // Insert current node data into map mp.set(p.data, true ); } // Return a vector of triplets. return v; } // Driver code let S = 15; // Create an empty singly linked list let head = null ; let ans = []; // Insert values in sorted order head = new Node(9) head.next = new Node(8) head.next.next = new Node(6) head.next.next.next = new Node(5) head.next.next.next.next = new Node(4) head.next.next.next.next.next = new Node(2) head.next.next.next.next.next.next = new Node(1) // Call printTriplets function // to find all triplets in // the linked list ans = printTriplets(head, S); // Sort and display // all possible triplets for (let i = 0; i < ans.length; i++) { ans[i].sort( function (a, b) { return a - b }) } ans.sort() for (let i = 0; i < ans.length; i++) { for (let j = 0; j < ans[i].length; j++) { document.write(ans[i][j] + " " ); } document.write( '<br>' ) } // This code is contributed by Potta Lokesh </script> |
1 5 9 1 6 8 2 4 9 2 5 8 4 5 6
Time Complexity: O(N2)
Auxiliary Space: O(N)