Find the k-th smallest divisor of a natural number N
You’re given a number N and a number K. Our task is to find the kth smallest divisor of N.
Examples:
Input : N = 12, K = 5
Output : 6
The divisors of 12 after sorting are 1, 2, 3, 4, 6 and 12.
Where the value of 5th divisor is equal to 6.
Input : N = 16, K 2
Output : 2
Simple Approach: A simple approach is to run a loop from 1 to √N and find all factors of N and push them into a vector. Finally, sort the vector and print the K-th value from the vector.
Note: Elements in the vector will not be sorted initially as we are pushing both factors (i) and (n/i). That is why it is needed to sort the vector before printing the K-th factor.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
void findkth( int n, int k)
{
vector< long long > v;
for ( int i = 1; i <= sqrt (n); i++) {
if (n % i == 0) {
v.push_back(i);
if (i != sqrt (n))
v.push_back(n / i);
}
}
sort(v.begin(), v.end());
if (k > v.size())
cout << "Doesn't Exist" ;
else
cout << v[k - 1];
}
int main()
{
int n = 15, k = 2;
findkth(n, k);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void findkth( int n, int k)
{
Vector<Integer> v = new Vector<Integer>();
for ( int i = 1 ; i <= Math.sqrt(n); i++) {
if (n % i == 0 ) {
v.add(i);
if (i != Math.sqrt(n))
v.add(n / i);
}
}
Collections.sort(v);
if (k > v.size())
System.out.print( "Doesn't Exist" );
else
System.out.print(v.get(k - 1 ));
}
public static void main(String[] args)
{
int n = 15 , k = 2 ;
findkth(n, k);
}
}
|
Python3
from math import sqrt
def findkth(n, k):
v = []
p = int (sqrt(n)) + 1
for i in range ( 1 , p, 1 ):
if (n % i = = 0 ):
v.append(i)
if (i ! = sqrt(n)):
v.append(n / i);
v.sort(reverse = False )
if (k > len (v)):
print ( "Doesn't Exist" )
else :
print (v[k - 1 ])
if __name__ = = '__main__' :
n = 15
k = 2
findkth(n, k)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void findkth( int n, int k)
{
List< int > v = new List< int >();
for ( int i = 1; i <= Math.Sqrt(n); i++) {
if (n % i == 0) {
v.Add(i);
if (i != Math.Sqrt(n))
v.Add(n / i);
}
}
v.Sort();
if (k > v.Count)
Console.Write( "Doesn't Exist" );
else
Console.Write(v[k - 1]);
}
public static void Main(String[] args)
{
int n = 15, k = 2;
findkth(n, k);
}
}
|
Javascript
<script>
function findkth( n, k)
{
var v=[];
for ( var i = 1; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
v.push(i);
if (i != Math.sqrt(n))
v.push(n / i);
}
}
v.sort( function fun(a,b){ return a-b });
if (k > v.length)
document.write( "Doesn't Exist" );
else
document.write( v[k - 1]);
}
var n = 15, k = 2;
findkth(n, k);
</script>
|
Time Complexity: √N log( √N )
Efficient Approach: An efficient approach will be to store the factors in two separate vectors. That is, factors i will be stored in a separate vector and N/i will be stored in a separate vector for all i from 1 to √N.
Now, if observed carefully, it can be seen that the first vector is already sorted in increasing order and the second vector is sorted in decreasing order. So, reverse the second vector and print the K-th element from either of the vectors in which it is lying.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findkth ( int n, int k)
{
vector < int > v1;
vector < int > v2;
for ( int i = 1 ; i <= sqrt ( n ); i++ )
{
if ( n % i == 0 )
{
v1.push_back ( i );
if ( i != sqrt ( n ) )
v2.push_back ( n / i );
}
}
reverse(v2.begin(), v2.end());
if ( k > (v1.size() + v2.size()))
cout << "Doesn't Exist" ;
else
{
if (k <= v1.size())
cout<<v1[k-1];
else
cout<<v2[k-v1.size()-1];
}
}
int main()
{
int n = 15, k = 2;
findkth ( n, k) ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void findkth ( int n, int k)
{
Vector<Integer> v1 = new Vector<Integer>();
Vector <Integer> v2 = new Vector<Integer>();
for ( int i = 1 ; i <= Math.sqrt( n ); i++ )
{
if ( n % i == 0 )
{
v1.add ( i );
if ( i != Math.sqrt ( n ) )
v2.add ( n / i );
}
}
Collections.reverse(v2);
if ( k > (v1.size() + v2.size()))
System.out.print( "Doesn't Exist" );
else
{
if (k <= v1.size())
System.out.print(v1.get(k - 1 ));
else
System.out.print(v2.get(k-v1.size() - 1 ));
}
}
public static void main(String[] args)
{
int n = 15 , k = 2 ;
findkth ( n, k) ;
}
}
|
Python3
import math as mt
def findkth (n, k):
v1 = list ()
v2 = list ()
for i in range ( 1 , mt.ceil(n * * (. 5 ))):
if (n % i = = 0 ):
v1.append(i)
if (i ! = mt.ceil(mt.sqrt(n))):
v2.append(n / / i)
v2[:: - 1 ]
if ( k > ( len (v1) + len (v2))):
print ( "Doesn't Exist" , end = "")
else :
if (k < = len (v1)):
print (v1[k - 1 ])
else :
print (v2[k - len (v1) - 1 ])
n = 15
k = 2
findkth (n, k)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void findkth ( int n, int k)
{
List< int > v1 = new List< int >();
List < int > v2 = new List< int >();
for ( int i = 1; i <= Math.Sqrt(n); i++)
{
if (n % i == 0)
{
v1.Add (i);
if (i != Math.Sqrt (n))
v2.Add (n / i);
}
}
v2.Reverse();
if (k > (v1.Count + v2.Count))
Console.Write( "Doesn't Exist" );
else
{
if (k <= v1.Count)
Console.Write(v1[k - 1]);
else
Console.Write(v2[k - v1.Count - 1]);
}
}
public static void Main(String[] args)
{
int n = 15, k = 2;
findkth (n, k);
}
}
|
Javascript
<script>
function findkth ( n,k)
{
let v1 = [];
let v2 = [];
for ( let i = 1 ; i <= Math.sqrt( n ); i++ )
{
if ( n % i == 0 )
{
v1.push ( i );
if ( i != Math.sqrt ( n ) )
v2.push ( n / i );
}
}
v2.reverse();
if ( k > (v1.length + v2.length))
document.write( "Doesn't Exist" );
else
{
if (k <= v1.length)
document.write(v1[k - 1]);
else
document.write(v2[k-v1.length - 1]);
}
}
let n = 15, k = 2;
findkth ( n, k) ;
</script>
|
Time Complexity: √N
Last Updated :
27 May, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...