N-th multiple in sorted list of multiples of two numbers
Last Updated :
12 Sep, 2023
Given three positive integers a, b and n. Consider a list that has all multiples of ‘a’ and ‘b’. the list is sorted and duplicates are removed. The task is to find n-th element of the list.
Examples :
Input : a = 3, b = 5, n = 5
Output : 10
a = 3 b = 5, Multiple of 3 are 3, 6, 9, 12, 15,... and
multiples of 5 are 5, 10, 15, 20,....
After deleting duplicate element and sorting:
3, 5, 6, 9, 10, 12, 15, 18, 20,....
The 5th element in the sequence is 10.
Input : n = 6, a = 2, b = 3
Output : 9
Method 1: (Brute Force)
Generate the first ‘n’ multiple of ‘a’. Now, generate first ‘n’ multiple of b such that it do not belong to the first n multiple of ‘a’. This can be done using Binary Search.
C++
#include<bits/stdc++.h>
using namespace std;
int nthElement( int a, int b, int n)
{
vector< int > seq;
for ( int i = 1; i <= n; i++)
seq.push_back(a*i);
sort(seq.begin(), seq.end());
for ( int i = 1, k = n; i <= n && k; i++)
{
if (!binary_search(seq.begin(), seq.end(), b*i))
{
seq.push_back(b*i);
sort(seq.begin(), seq.end());
k--;
}
}
return seq[n - 1];
}
int main()
{
int a = 3, b = 5, n = 5;
cout << nthElement(a, b, n) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int nthElement( int a, int b, int n)
{
ArrayList<Integer> seq = new
ArrayList<Integer>(n * n + 1 );
for ( int i = 1 ; i <= n; i++)
seq.add(a * i);
Collections.sort(seq);
for ( int i = 1 , k = n;
i <= n && k > 0 ; i++)
{
if (seq.indexOf(b * i) == - 1 )
{
seq.add(b * i);
Collections.sort(seq);
k--;
}
}
return seq.get(n - 1 );
}
public static void main(String[] args)
{
int a = 3 , b = 5 , n = 5 ;
System.out.println(nthElement(a, b, n));
}
}
|
Python3
def nthElement(a, b, n):
seq = [];
for i in range ( 1 , n + 1 ):
seq.append(a * i);
seq.sort();
i = 1 ;
k = n;
while (i < = n and k > 0 ):
try :
z = seq.index(b * i);
except ValueError:
seq.append(b * i);
seq.sort();
k - = 1 ;
i + = 1 ;
return seq[n - 1 ];
a = 3 ;
b = 5 ;
n = 5 ;
print (nthElement(a, b, n));
|
C#
using System;
using System.Collections;
class GFG
{
static int nthElement( int a,
int b, int n)
{
ArrayList seq = new ArrayList();
for ( int i = 1; i <= n; i++)
seq.Add(a * i);
seq.Sort();
for ( int i = 1, k = n;
i <= n && k > 0; i++)
{
if (!seq.Contains(b * i))
{
seq.Add(b * i);
seq.Sort();
k--;
}
}
return ( int )seq[n - 1];
}
static void Main()
{
int a = 3, b = 5, n = 5;
Console.WriteLine(nthElement(a, b, n));
}
}
|
Javascript
<script>
function nthElement(a, b, n)
{
let seq = [];
for (let i = 1; i <= n; i++)
seq.push(a * i);
seq.sort( function (a, b){ return a - b});
for (let i = 1, k = n;
i <= n && k > 0; i++)
{
if (!seq.includes(b * i))
{
seq.push(b * i);
seq.sort( function (a, b){ return a - b});
k--;
}
}
return seq[n - 1];
}
let a = 3, b = 5, n = 5;
document.write(nthElement(a, b, n));
</script>
|
PHP
<?php
function nthElement( $a , $b , $n )
{
$seq = array ();
for ( $i = 1; $i <= $n ; $i ++)
array_push ( $seq , $a * $i );
sort( $seq );
for ( $i = 1, $k = $n ;
$i <= $n && $k > 0; $i ++)
{
if ( array_search ( $b * $i , $seq ) == 0)
{
array_push ( $seq , $b * $i );
sort( $seq );
$k --;
}
}
return $seq [ $n - 1];
}
$a = 3;
$b = 5;
$n = 5;
echo nthElement( $a , $b , $n );
?>
|
Output:
10
Time Complexity: O(n2 log2n)
Auxiliary Space: O(n)
Method 2: (Efficient Approach)
The idea is to use the fact that common multiple of a and b are removed using LCM(a, b). Let f(a, b, x) be a function which calculates the count of number that are less than x and multiples of a and b. Now, using the inclusion-exclusion principle we can say,
f(a, b, x) : Count of number that are less than x
and multiples of a and b
f(a, b, x) = (x/a) + (x/b) - (x/lcm(a, b))
where (x/a) define number of multiples of a
(x/b) define number of multiple of b
(x/lcm(a, b)) define the number of common multiples
of a and b.
Observe, a and b are constant. As x increases, f(a, b, x) will also increase. Therefore we can apply Binary Search to find the minimum value of x such that f(a, b, x) >= n. The lower bound of the function is the required answer.
The upper bound for n-th term would be min(a, b)*n. Note that we get the largest value n-th term when there are no common elements in multiples of a and b.
Below are the implementations of above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int nthElement( int a, int b, int n)
{
int lcm = (a * b)/__gcd(a,b);
int l = 1, r = min(a, b)*n;
while (l <= r)
{
int mid = (l + r)>>1;
int val = mid/a + mid/b - mid/lcm;
if (val == n)
return max((mid/a)*a, (mid/b)*b);
if (val < n)
l = mid + 1;
else
r = mid - 1;
}
}
int main()
{
int a = 5, b = 3, n = 5;
cout << nthElement(a, b, n) << endl;
return 0;
}
|
Java
import java.io.*;
public class GFG{
static int __gcd( int a, int b)
{
if (a == 0 || b == 0 )
return 0 ;
if (a == b)
return a;
if (a > b)
return __gcd(a - b, b);
return __gcd(a, b - a);
}
static int nthElement( int a, int b, int n)
{
int lcm = (a * b) / __gcd(a, b);
int l = 1 , r = Math.min(a, b) * n;
while (l <= r)
{
int mid = (l + r) >> 1 ;
int val = mid / a + mid / b -
mid / lcm;
if (val == n)
return Math.max((mid / a) * a,
(mid / b) * b);
if (val < n)
l = mid + 1 ;
else
r = mid - 1 ;
}
return 0 ;
}
static public void main (String[] args)
{
int a = 5 , b = 3 , n = 5 ;
System.out.println(nthElement(a, b, n));
}
}
|
Python 3
import math
def nthElement(a, b, n):
lcm = (a * b) / int (math.gcd(a, b))
l = 1
r = min (a, b) * n
while (l < = r):
mid = (l + r) >> 1
val = ( int (mid / a) + int (mid / b)
- int (mid / lcm))
if (val = = n):
return int ( max ( int (mid / a) * a,
int (mid / b) * b) )
if (val < n):
l = mid + 1
else :
r = mid - 1
a = 5
b = 3
n = 5
print (nthElement(a, b, n))
|
C#
using System;
public class GFG{
static int __gcd( int a, int b)
{
if (a == 0 || b == 0)
return 0;
if (a == b)
return a;
if (a > b)
return __gcd(a - b, b);
return __gcd(a, b - a);
}
static int nthElement( int a, int b, int n)
{
int lcm = (a * b) / __gcd(a, b);
int l = 1, r = Math.Min(a, b) * n;
while (l <= r)
{
int mid = (l + r) >> 1;
int val = mid / a + mid / b -
mid / lcm;
if (val == n)
return Math.Max((mid / a) * a,
(mid / b) * b);
if (val < n)
l = mid + 1;
else
r = mid - 1;
}
return 0;
}
static public void Main (String []args)
{
int a = 5, b = 3, n = 5;
Console.WriteLine(nthElement(a, b, n));
}
}
|
PHP
<?php
function gcd( $a , $b )
{
return ( $a % $b ) ?
gcd( $b , $a % $b ) : $b ;
}
function nthElement( $a , $b , $n )
{
$lcm = (int)(( $a * $b ) / gcd( $a , $b ));
$l = 1;
$r = min( $a , $b ) * $n ;
while ( $l <= $r )
{
$mid = ( $l + $r ) >> 1;
$val = (int)( $mid / $a ) +
(int)( $mid / $b ) -
(int)( $mid / $lcm );
if ( $val == $n )
return max((int)(( $mid / $a )) * $a ,
(int)(( $mid / $b )) * $b );
if ( $val < $n )
$l = $mid + 1;
else
$r = $mid - 1;
}
}
$a = 5;
$b = 3;
$n = 5;
echo nthElement( $a , $b , $n );
?>
|
Javascript
<script>
function __gcd(a , b)
{
if (a == 0 || b == 0)
return 0;
if (a == b)
return a;
if (a > b)
return __gcd(a - b, b);
return __gcd(a, b - a);
}
function nthElement(a , b , n)
{
var lcm = parseInt((a * b) / __gcd(a, b));
var l = 1, r = Math.min(a, b) * n;
while (l <= r)
{
var mid = (l + r) >> 1;
var val = parseInt(mid / a) + parseInt(mid / b) -
parseInt(mid / lcm);
if (val == n)
return Math.max(parseInt(mid / a) * a,
parseInt(mid / b) * b);
if (val < n)
l = mid + 1;
else
r = mid - 1;
}
return 0;
}
var a = 5, b = 3, n = 5;
document.write(nthElement(a, b, n));
</script>
|
Output:
10
Time Complexity: O(log n)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...