Given a sorted doubly linked list of distinct nodes(no two nodes have the same data) and a value x. The task is to count the triplets in the list that product up to a given value x.
Examples:
Input: list = 1->2->4->5->6->8->9, x = 8
Output: 1
Triplet is (1, 2, 4)
Input: list = 1->2->4->5->6->8->9, x = 120
Output: 1
Triplet is (4, 5, 6)
Naive Approach: Using three nested loops generate all triplets and check whether elements in the triplet product up to x or not.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *next, *prev;
};
int countTriplets( struct Node* head, int x)
{
struct Node *ptr1, *ptr2, *ptr3;
int count = 0;
for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next)
for (ptr2 = ptr1->next; ptr2 != NULL; ptr2 = ptr2->next)
for (ptr3 = ptr2->next; ptr3 != NULL; ptr3 = ptr3->next)
if ((ptr1->data * ptr2->data * ptr3->data) == x)
count++;
return count;
}
void insert( struct Node** head, int data)
{
struct Node* temp = new Node();
temp->data = data;
temp->next = temp->prev = NULL;
if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
int main()
{
struct Node* head = NULL;
insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);
int x = 8;
cout << "Count = "
<< countTriplets(head, x);
return 0;
}
|
Java
import java.util.*;
class Node
{
public int data;
public Node prev, next;
public Node( int val)
{
data = val;
prev = null ;
next = null ;
}
}
class GFG
{
static int countTriplets(Node head, int x)
{
Node ptr1, ptr2, ptr3;
int count = 0 ;
for (ptr1 = head; ptr1 != null ; ptr1 = ptr1.next)
for (ptr2 = ptr1.next; ptr2 != null ; ptr2 = ptr2.next)
for (ptr3 = ptr2.next; ptr3 != null ; ptr3 = ptr3.next)
if ((ptr1.data * ptr2.data * ptr3.data) == x)
count++;
return count;
}
static Node insert(Node head, int val)
{
Node temp = new Node(val);
if (head == null )
head = temp;
else
{
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
public static void main(String []args)
{
Node head = null ;
head = insert(head, 9 );
head = insert(head, 8 );
head = insert(head, 6 );
head = insert(head, 5 );
head = insert(head, 4 );
head = insert(head, 2 );
head = insert(head, 1 );
int x = 8 ;
System.out.println( "count = " + countTriplets(head, x));
}
}
|
Python3
class Node:
data = None
prev = None
next_ = None
def __init__( self , val):
self .data = val
self .prev = None
self .next_ = None
def countTriplets(head, x):
ptr1, ptr2, ptr3 = Node( 0 ), Node( 0 ), Node( 0 )
count = 0
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 = = x:
count + = 1
ptr3 = ptr3.next_
ptr2 = ptr2.next_
ptr1 = ptr1.next_
return count
def insert(head, val):
temp = Node(val)
if head is None :
head = temp
else :
temp.next_ = head
head.prev = temp
head = temp
return head
if __name__ = = "__main__" :
head = Node( 0 )
head = insert(head, 9 )
head = insert(head, 8 )
head = insert(head, 6 )
head = insert(head, 5 )
head = insert(head, 4 )
head = insert(head, 2 )
head = insert(head, 1 )
x = 8
print ( "count =" , countTriplets(head, x))
|
C#
using System;
public class Node
{
public int data;
public Node prev, next;
public Node( int val)
{
data = val;
prev = null ;
next = null ;
}
}
class GFG
{
static int countTriplets(Node head, int x)
{
Node ptr1, ptr2, ptr3;
int count = 0;
for (ptr1 = head; ptr1 != null ; ptr1 = ptr1.next)
for (ptr2 = ptr1.next; ptr2 != null ; ptr2 = ptr2.next)
for (ptr3 = ptr2.next; ptr3 != null ; ptr3 = ptr3.next)
if ((ptr1.data * ptr2.data * ptr3.data) == x)
count++;
return count;
}
static Node insert(Node head, int val)
{
Node temp = new Node(val);
if (head == null )
head = temp;
else
{
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
public static void Main(String []args)
{
Node head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
int x = 8;
Console.WriteLine( "count = " + countTriplets(head, x));
}
}
|
Javascript
<script>
class Node {
constructor(val) {
this .data = val;
this .prev = null ;
this .next = null ;
}
}
function countTriplets( head , x) {
var ptr1, ptr2, ptr3;
var count = 0;
for (ptr1 = head; ptr1 != null ; ptr1 = ptr1.next)
for (ptr2 = ptr1.next; ptr2 != null ; ptr2 = ptr2.next)
for (ptr3 = ptr2.next; ptr3 != null ; ptr3 = ptr3.next)
if ((ptr1.data * ptr2.data * ptr3.data) == x)
count++;
return count;
}
function insert( head , val) {
temp = new Node(val);
if (head == null )
head = temp;
else {
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
var x = 8;
document.write( "count = " + countTriplets(head, x));
</script>
|
Complexity Analysis:
- Time Complexity: O(n^3)
- Auxiliary Space: O(1)
Method-2 (Hashing):
Create a hash table with (key, value) tuples represented as (node data, node pointer) tuples. Traverse the doubly linked list and store each node’s data and its pointer pair(tuple) in the hash table. Now, generate each possible pair of nodes. For each pair of nodes, calculate the p_product(product of data in the two nodes) and check whether (x/p_product) exists in the hash table or not.
If it exists, then also verify that the two nodes in the pair are not same as to the node associated with (x/p_product) in the hash table and finally increment count. Return (count / 3) as each triplet is counted 3 times in the above process.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *next, *prev;
};
int countTriplets( struct Node* head, int x)
{
struct Node *ptr, *ptr1, *ptr2;
int count = 0;
unordered_map< int , Node*> um;
for (ptr = head; ptr != NULL; ptr = ptr->next)
um[ptr->data] = ptr;
for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next)
for (ptr2 = ptr1->next; ptr2 != NULL; ptr2 = ptr2->next) {
int p_product = (ptr1->data * ptr2->data);
if (um.find(x / p_product) != um.end() && um[x / p_product] != ptr1
&& um[x / p_product] != ptr2)
count++;
}
return (count / 3);
}
void insert( struct Node** head, int data)
{
struct Node* temp = new Node();
temp->data = data;
temp->next = temp->prev = NULL;
if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
int main()
{
struct Node* head = NULL;
insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);
int x = 8;
cout << "Count = "
<< countTriplets(head, x);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Node
{
int data;
Node next, prev;
}
class GFG{
static int countTriplets(Node head, int x)
{
Node ptr, ptr1, ptr2;
int count = 0 ;
Map<Integer,
Node> um = new HashMap<Integer,
Node>();
for (ptr = head; ptr != null ; ptr = ptr.next)
{
um.put(ptr.data, ptr);
}
for (ptr1 = head;
ptr1 != null ;
ptr1 = ptr1.next)
{
for (ptr2 = ptr1.next;
ptr2 != null ;
ptr2 = ptr2.next)
{
int p_product = (ptr1.data * ptr2.data);
if (um.containsKey(x / p_product) &&
um.get(x / p_product) != ptr1 &&
um.get(x / p_product) != ptr2)
{
count++;
}
}
}
return (count / 3 );
}
static Node insert(Node head, int data)
{
Node temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if (head == null )
{
head = temp;
}
else
{
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
public static void main(String[] args)
{
Node head = null ;
head = insert(head, 9 );
head = insert(head, 8 );
head = insert(head, 6 );
head = insert(head, 5 );
head = insert(head, 4 );
head = insert(head, 2 );
head = insert(head, 1 );
int x = 8 ;
System.out.println( "Count = " +
countTriplets(head, x));
}
}
|
Python3
from math import ceil
class Node:
def __init__( self , x):
self .data = x
self . next = None
self .prev = None
def countTriplets(head, x):
ptr, ptr1, ptr2 = None , None , None
count = 0
um = {}
ptr = head
while ptr ! = None :
um[ptr.data] = ptr
ptr = ptr. next
ptr1 = head
while ptr1 ! = None :
ptr2 = ptr1. next
while ptr2 ! = None :
p_product = (ptr1.data *
ptr2.data)
if ((x / p_product) in um and
(x / p_product) ! = ptr1 and
um[x / p_product] ! = ptr2):
count + = 1
ptr2 = ptr2. next
ptr1 = ptr1. next
return (count / / 3 )
def insert(head, data):
temp = Node(data)
temp.data = data
temp. next = temp.prev = None
if (head = = None ):
head = temp
else :
temp. next = head
head.prev = temp
head = temp
return head
if __name__ = = '__main__' :
head = None
head = insert(head, 9 )
head = insert(head, 8 )
head = insert(head, 6 )
head = insert(head, 5 )
head = insert(head, 4 )
head = insert(head, 2 )
head = insert(head, 1 )
x = 8
print ( "Count =" ,
countTriplets(head, x))
|
C#
using System;
using System.Collections.Generic;
class Node
{
public int data;
public Node next, prev;
}
class GFG
{
static int countTriplets(Node head, int x)
{
Node ptr, ptr1, ptr2;
int count = 0;
Dictionary< int , Node> um = new Dictionary< int , Node>();
for (ptr = head; ptr != null ; ptr = ptr.next)
{
um.Add(ptr.data, ptr);
}
for (ptr1 = head;
ptr1 != null ;
ptr1 = ptr1.next)
{
for (ptr2 = ptr1.next;
ptr2 != null ;
ptr2 = ptr2.next)
{
int p_product = (ptr1.data * ptr2.data);
if (um.ContainsKey(x / p_product) &&
um[x / p_product] != ptr1 &&
um[x / p_product] != ptr2)
{
count++;
}
}
}
return (count / 3);
}
static Node insert(Node head, int data)
{
Node temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if (head == null )
{
head = temp;
}
else
{
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
static public void Main ()
{
Node head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
int x = 8;
Console.WriteLine( "Count = " + countTriplets(head, x));
}
}
|
Javascript
<script>
class Node
{
constructor(data)
{
this .data=data;
this .next= this .prev= null ;
}
}
function countTriplets(head,x)
{
let ptr, ptr1, ptr2;
let count = 0;
let um = new Map();
for (ptr = head; ptr != null ; ptr = ptr.next)
{
um.set(ptr.data, ptr);
}
for (ptr1 = head;
ptr1 != null ;
ptr1 = ptr1.next)
{
for (ptr2 = ptr1.next;
ptr2 != null ;
ptr2 = ptr2.next)
{
let p_product = (ptr1.data * ptr2.data);
if (um.has(x / p_product) &&
um.get(x / p_product) != ptr1 &&
um.get(x / p_product) != ptr2)
{
count++;
}
}
}
return (count / 3);
}
function insert(head,data)
{
let temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if (head == null )
{
head = temp;
}
else
{
temp.next = head;
head.prev = temp;
head = temp;
}
return head;
}
let head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
let x = 8;
document.write( "Count = " +
countTriplets(head, x));
</script>
|
Complexity Analysis:
- Time Complexity: O(n^2)
- Auxiliary Space: O(n)
Method-3 (Use of two pointers):
Traverse the doubly linked list from left to right. For each current node during the traversal, initialize two pointers first = pointer to the node next to the current node and last = pointer to the last node of the list. Now, count pairs in the list from first to the last pointer that product up to the value (x / current node’s data) (algorithm described in this post). Add this count to the total_count of triplets. Pointer to the last node can be found only once in the beginning.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *next, *prev;
};
int countPairs( struct Node* first, struct Node* second, int value)
{
int count = 0;
while (first != NULL && second != NULL && first != second
&& second->next != first) {
if ((first->data * second->data) == value) {
count++;
first = first->next;
second = second->prev;
}
else if ((first->data * second->data) > value)
second = second->prev;
else
first = first->next;
}
return count;
}
int countTriplets( struct Node* head, int x)
{
if (head == NULL)
return 0;
struct Node *current, *first, *last;
int count = 0;
last = head;
while (last->next != NULL)
last = last->next;
for (current = head; current != NULL; current = current->next) {
first = current->next;
count += countPairs(first, last, x / current->data);
}
return count;
}
void insert( struct Node** head, int data)
{
struct Node* temp = new Node();
temp->data = data;
temp->next = temp->prev = NULL;
if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
int main()
{
struct Node* head = NULL;
insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);
int x = 8;
cout << "Count = "
<< countTriplets(head, x);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node next, prev;
};
static int countPairs(Node first, Node second,
int value)
{
int count = 0 ;
while (first != null && second != null &&
first != second && second.next != first)
{
if ((first.data * second.data) == value)
{
count++;
first = first.next;
second = second.prev;
}
else if ((first.data * second.data) > value)
second = second.prev;
else
first = first.next;
}
return count;
}
static int countTriplets(Node head, int x)
{
if (head == null )
return 0 ;
Node current, first, last;
int count = 0 ;
last = head;
while (last.next != null )
last = last.next;
for (current = head; current != null ;
current = current.next)
{
first = current.next;
count += countPairs(first, last, x / current.data);
}
return count;
}
static Node insert(Node head, int data)
{
Node temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if ((head) == null )
(head) = temp;
else
{
temp.next = head;
(head).prev = temp;
(head) = temp;
}
return head;
}
public static void main(String args[])
{
Node head = null ;
head = insert(head, 9 );
head = insert(head, 8 );
head = insert(head, 6 );
head = insert(head, 5 );
head = insert(head, 4 );
head = insert(head, 2 );
head = insert(head, 1 );
int x = 8 ;
System.out.println( "Count = " + countTriplets(head, x));
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
self .prev = None
def countPairs(first, second, value):
count = 0
while (first ! = None and second ! = None and
first ! = second and second. next ! = first):
if ((first.data * second.data) = = value):
count + = 1
first = first. next
second = second.prev
elif ((first.data * second.data) > value):
second = second.prev
else :
first = first. next
return count
def countTriplets(head, x):
if (head = = None ):
return 0
count = 0
last = head
while (last. next ! = None ):
last = last. next
current = head
while current ! = None :
first = current. next
count + = countPairs(first, last,
x / / current.data)
current = current. next
return count
def insert(head, data):
temp = Node(data)
temp.data = data
temp. next = temp.prev = None
if ((head) = = None ):
(head) = temp
else :
temp. next = head
(head).prev = temp
(head) = temp
return head
if __name__ = = '__main__' :
head = None
head = insert(head, 9 )
head = insert(head, 8 )
head = insert(head, 6 )
head = insert(head, 5 )
head = insert(head, 4 )
head = insert(head, 2 )
head = insert(head, 1 )
x = 8
print ( "Count = " + str (countTriplets(head, x)))
|
C#
using System;
class GFG
{
class Node
{
public int data;
public Node next, prev;
};
static int countPairs(Node first, Node second,
int value)
{
int count = 0;
while (first != null && second != null &&
first != second && second.next != first)
{
if ((first.data * second.data) == value)
{
count++;
first = first.next;
second = second.prev;
}
else if ((first.data * second.data) > value)
second = second.prev;
else
first = first.next;
}
return count;
}
static int countTriplets(Node head, int x)
{
if (head == null )
return 0;
Node current, first, last;
int count = 0;
last = head;
while (last.next != null )
last = last.next;
for (current = head; current != null ;
current = current.next)
{
first = current.next;
count += countPairs(first, last, x / current.data);
}
return count;
}
static Node insert(Node head, int data)
{
Node temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if ((head) == null )
(head) = temp;
else
{
temp.next = head;
(head).prev = temp;
(head) = temp;
}
return head;
}
public static void Main(String []args)
{
Node head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
int x = 8;
Console.WriteLine( "Count = " + countTriplets(head, x));
}
}
|
Javascript
<script>
class Node
{
constructor()
{
let data;
let next, prev;
}
}
function countPairs(first,second,value)
{
let count = 0;
while (first != null && second != null &&
first != second && second.next != first)
{
if ((first.data * second.data) == value)
{
count++;
first = first.next;
second = second.prev;
}
else if ((first.data * second.data) > value)
second = second.prev;
else
first = first.next;
}
return count;
}
function countTriplets(head,x)
{
if (head == null )
return 0;
let current, first, last;
let count = 0;
last = head;
while (last.next != null )
last = last.next;
for (current = head; current != null ;
current = current.next)
{
first = current.next;
count += countPairs(first, last, x / current.data);
}
return count;
}
function insert(head,data)
{
let temp = new Node();
temp.data = data;
temp.next = temp.prev = null ;
if ((head) == null )
(head) = temp;
else
{
temp.next = head;
(head).prev = temp;
(head) = temp;
}
return head;
}
let head = null ;
head = insert(head, 9);
head = insert(head, 8);
head = insert(head, 6);
head = insert(head, 5);
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 1);
let x = 8;
document.write( "Count = " + countTriplets(head, x));
</script>
|
Complexity Analysis:
- Time Complexity: O(n^2)
- Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!