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:
The idea is to use three nested loop and after that Generate all triplets and find the distinct triplets having sum equal to S.
Algorithm
- Initialize a variable called “triplets” as an empty list.
- Traverse the linked list with three nested loops to generate all possible triplets.
- For each triplet, check if the sum of the values is equal to S and if the triplet is distinct
- If both conditions are true, append the triplet to the “triplets” list.
- Return the “triplets” list.
Implementation of the above approach
#include <iostream> #include <tuple> #include <vector> using namespace std;
// define the Node class class Node {
public :
int data;
Node* next;
Node( int data)
{
this ->data = data;
this ->next = NULL;
}
}; // function to find triplets in the linked list vector<tuple< int , int , int > > findTriplets(Node* head,
int S)
{ vector<tuple< int , int , int > >
triplets; // initialize empty vector to store
// triplets
Node* ptr1
= head; // pointer to traverse the linked list
while (ptr1 != NULL) {
Node* ptr2 = ptr1->next; // pointer to traverse the
// remaining part of the
// linked list
while (ptr2 != NULL) {
Node* ptr3 = ptr2->next; // pointer to traverse
// the remaining part
// of the linked list
while (ptr3 != NULL) {
if (ptr1->data + ptr2->data + ptr3->data
== S) { // check if sum of values is
// equal to S
if (ptr1->data != ptr2->data
&& ptr1->data != ptr3->data
&& ptr2->data != ptr3->data) {
// check if triplet is distinct
// (i.e., all elements are unique)
tuple< int , int , int > triplet
= make_tuple(ptr1->data,
ptr2->data,
ptr3->data);
triplets.push_back(
triplet); // add triplet to the
// vector
}
}
ptr3 = ptr3->next; // move ptr3 to its next
// node
}
ptr2 = ptr2->next; // move ptr2 to its next node
}
ptr1 = ptr1->next; // move ptr1 to its next node
}
return triplets; // return the vector of triplets
} // main function to test the code int main()
{ Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(4);
head->next->next->next = new Node(5);
head->next->next->next->next = new Node(6);
head->next->next->next->next->next = new Node(8);
head->next->next->next->next->next->next = new Node(9);
int S = 15;
vector<tuple< int , int , int > > triplets
= findTriplets(head, S);
for ( auto triplet : triplets) {
cout << "(" << get<0>(triplet) << ", "
<< get<1>(triplet) << ", " << get<2>(triplet)
<< ")" << endl;
}
return 0;
} |
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
// Define the Node class for the linked list class Node {
int data;
Node next;
public Node( int data) {
this .data = data;
this .next = null ;
}
} public class TripletsInLinkedList {
// Function to find triplets in the linked list that sum to S
public static List<Triplet> findTriplets(Node head, int S) {
List<Triplet> triplets = new ArrayList<>();
Node ptr1 = head;
while (ptr1 != null ) {
Node ptr2 = ptr1.next;
while (ptr2 != null ) {
Node ptr3 = ptr2.next;
while (ptr3 != null ) {
if (ptr1.data + ptr2.data + ptr3.data == S) {
// Check if the triplet is distinct (all elements are unique)
if (ptr1.data != ptr2.data && ptr1.data != ptr3.data && ptr2.data != ptr3.data) {
Triplet triplet = new Triplet(ptr1.data, ptr2.data, ptr3.data);
triplets.add(triplet);
}
}
ptr3 = ptr3.next;
}
ptr2 = ptr2.next;
}
ptr1 = ptr1.next;
}
return triplets;
}
// Main function to test the code
public static void main(String[] args) {
Node head = new Node( 1 );
head.next = new Node( 2 );
head.next.next = new Node( 4 );
head.next.next.next = new Node( 5 );
head.next.next.next.next = new Node( 6 );
head.next.next.next.next.next = new Node( 8 );
head.next.next.next.next.next.next = new Node( 9 );
int S = 15 ;
List<Triplet> triplets = findTriplets(head, S);
for (Triplet triplet : triplets) {
System.out.println( "(" + triplet.first + ", " + triplet.second + ", " + triplet.third + ")" );
}
}
// Define a custom Triplet class to store the triplet values
static class Triplet {
int first, second, third;
Triplet( int first, int second, int third) {
this .first = first;
this .second = second;
this .third = third;
}
@Override
public boolean equals(Object o) {
if ( this == o) return true ;
if (o == null || getClass() != o.getClass()) return false ;
Triplet triplet = (Triplet) o;
return first == triplet.first && second == triplet.second && third == triplet.third;
}
@Override
public int hashCode() {
return Objects.hash(first, second, third);
}
}
} |
class Node:
def __init__( self , data):
self .data = data
self . next = None
# Function to find triplets in the linked list with a given sum S def find_triplets(head, S):
triplets = [] # Initialize an empty list to store triplets
ptr1 = head
while ptr1 is not None :
ptr2 = ptr1. next
while ptr2 is not None :
ptr3 = ptr2. next
while ptr3 is not None :
if ptr1.data + ptr2.data + ptr3.data = = S:
if ptr1.data ! = ptr2.data and ptr1.data ! = ptr3.data and ptr2.data ! = ptr3.data:
# Check if the triplet is distinct (i.e., all elements are unique)
triplet = (ptr1.data, ptr2.data, ptr3.data)
triplets.append(triplet) # Add triplet to the list
ptr3 = ptr3. next
ptr2 = ptr2. next
ptr1 = ptr1. next
return triplets
def main():
# Create a linked list
head = Node( 1 )
head. next = Node( 2 )
head. next . next = Node( 4 )
head. next . next . next = Node( 5 )
head. next . next . next . next = Node( 6 )
head. next . next . next . next . next = Node( 8 )
head. next . next . next . next . next . next = Node( 9 )
S = 15
triplets = find_triplets(head, S) # Find triplets with the sum S
for triplet in triplets:
print (f "({triplet[0]}, {triplet[1]}, {triplet[2]})" ) # Print the found triplets
if __name__ = = "__main__" :
main()
|
using System;
using System.Collections.Generic;
class Program
{ // Define the Node class
class Node
{
public int Data { get ; set ; }
public Node Next { get ; set ; }
public Node( int data)
{
Data = data;
Next = null ;
}
}
// Function to find triplets in the linked list
static List<Tuple< int , int , int >> FindTriplets(Node head, int S)
{
List<Tuple< int , int , int >> triplets = new List<Tuple< int , int , int >>();
Node ptr1 = head;
while (ptr1 != null )
{
Node ptr2 = ptr1.Next;
while (ptr2 != null )
{
Node ptr3 = ptr2.Next;
while (ptr3 != null )
{
if (ptr1.Data + ptr2.Data + ptr3.Data == S)
{
// Check if the triplet elements are distinct
if (ptr1.Data != ptr2.Data
&& ptr1.Data != ptr3.Data
&& ptr2.Data != ptr3.Data)
{
// Add the valid triplet to the list
triplets.Add(Tuple.Create(ptr1.Data, ptr2.Data, ptr3.Data));
}
}
ptr3 = ptr3.Next;
}
ptr2 = ptr2.Next;
}
ptr1 = ptr1.Next;
}
return triplets;
}
// Main function to test the code
static void Main()
{
// Create a linked list with nodes
Node head = new Node(1);
head.Next = new Node(2);
head.Next.Next = new Node(4);
head.Next.Next.Next = new Node(5);
head.Next.Next.Next.Next = new Node(6);
head.Next.Next.Next.Next.Next = new Node(8);
head.Next.Next.Next.Next.Next.Next = new Node(9);
int S = 15;
// Find triplets in the linked list with the specified sum
List<Tuple< int , int , int >> triplets = FindTriplets(head, S);
// Print the found triplets
foreach ( var triplet in triplets)
{
Console.WriteLine($ "({triplet.Item1}, {triplet.Item2}, {triplet.Item3})" );
}
}
} |
// Define the Node class class Node { constructor(data) {
this .data = data;
this .next = null ;
}
} // Function to find triplets in the linked list function findTriplets(head, S) {
const triplets = []; // Initialize empty array to store triplets
let ptr1 = head;
// Pointer to traverse the linked list
while (ptr1 !== null ) {
let ptr2 = ptr1.next;
// Pointer to traverse the remaining part of the linked list
while (ptr2 !== null ) {
let ptr3 = ptr2.next;
// Pointer to traverse the remaining part of the linked list
while (ptr3 !== null ) {
if (ptr1.data + ptr2.data + ptr3.data === S) {
// Check if the sum of values is equal to S
if (
ptr1.data !== ptr2.data &&
ptr1.data !== ptr3.data &&
ptr2.data !== ptr3.data
) {
// Check if triplet is distinct (i.e., all elements are unique)
const triplet = [ptr1.data, ptr2.data, ptr3.data];
triplets.push(triplet); // Add triplet to the array
}
}
ptr3 = ptr3.next; // Move ptr3 to its next node
}
ptr2 = ptr2.next; // Move ptr2 to its next node
}
ptr1 = ptr1.next; // Move ptr1 to its next node
}
return triplets; // Return the array of triplets
} // Main function to test the code function main() {
const head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(4);
head.next.next.next = new Node(5);
head.next.next.next.next = new Node(6);
head.next.next.next.next.next = new Node(8);
head.next.next.next.next.next.next = new Node(9);
const S = 15;
const triplets = findTriplets(head, S);
for (const triplet of triplets) {
console.log(`(${triplet[0]}, ${triplet[1]}, ${triplet[2]})`);
}
} main(); |
(1, 5, 9) (1, 6, 8) (2, 4, 9) (2, 5, 8) (4, 5, 6)
Time Complexity: O(N3)
Auxiliary Space: O(N3)
Efficient Approach: Use the 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++ 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 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. |
# Python code to find all distinct triplets having sum S class Node:
def __init__( self , data):
self .data = data
self . next = None
def printTriplets(head, S):
# Declare a dictionary
# to store the scanned value
mp = {}
# List to store the triplets
v = []
# Declare two pointers 'p' and 'q'
# for traversing singly linked list
p = head
q = head. next
# Insert 1st node data into map
# and start traversing from next node
mp[head.data] = True
# Outer loop terminates
# when last node reached
while q:
if q:
# Inner loop terminates
# when second pointer become None
r = q. next
while r:
# Temporary list
# to store the current triplet
temp = []
second = q.data
third = r.data
# find the number required
# to make triplet by subtracting
# node1 and node2 data from S
# and store it.
first = S - second - third
# Search if that value
# is present in the map or not
if first in mp:
# If 'first' is present
# in map, make a triplet of
# first,second & third
temp.append(first)
temp.append(second)
temp.append(third)
v.append(temp)
r = r. next
if q:
mp[q.data] = True
q = q. next
# Return a list of triplets.
return v
# Driver code if __name__ = = '__main__' :
S = 15
# Create an empty singly linked list
head = Node( 9 )
head. next = Node( 8 )
head. next . next = Node( 6 )
head. next . next . next = Node( 5 )
head. next . next . next . next = Node( 4 )
head. next . next . next . next . next = Node( 2 )
head. next . next . next . next . next . next = Node( 1 )
# Call printTriplets function
# to find all triplets in
# the linked list
ans = printTriplets(head, S)
# Sort and display
# all possible triplets
for i in ans:
i.sort()
ans.sort(key = lambda x: (x[ 0 ], x[ 1 ], x[ 2 ]))
for i in ans:
for j in i:
print (j, end = ' ' )
print ()
# This code is contributed by lokeshmvs21. |
// C# code to find all distinct // triplets having sum S using System;
using System.Collections.Generic;
using System.Linq;
public class GFG {
// Structure of node of singly linked list
class Node {
public int data;
public 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'
static List<List< int > > PrintTriplets(Node head, int S)
{
// Declare unordered map
// to store the scanned value
var mp = new Dictionary< int , bool >();
// Vector to store the triplets
var v = new List<List< int > >();
// 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.Add(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
var temp = new List< int >();
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.Add(p.data, true );
}
// Return a vector of triplets.
return v;
}
static public void Main()
{
// Code
int S = 15;
// Create an empty singly linked list
Node head = null ;
var ans = new List<List< int > >();
// 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
foreach ( var x in ans) { x.Sort(); }
ans = ans.OrderBy(x = > x[0])
.ThenBy(x = > x[1])
.ThenBy(x = > x[2])
.ToList();
for ( int i = 0; i < ans.Count; i++) {
for ( int j = 0; j < ans[i].Count; j++) {
Console.Write(ans[i][j] + " " );
}
Console.WriteLine();
}
}
} // This code is contributed by lokesh. |
<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)