Given a number n, find the n-th square-free number. A number is square-free if it is not divisible by a perfect square other than 1.
Examples :
Input : n = 2
Output : 2
Input : 5
Output : 6
There is one number (in range from 1 to 6)
that is divisible by a square. The number
is 4.
Method 1 (Brute Force):
The idea is to iteratively check every number whether it is divisible by any perfect square number and increase the count whenever an square free number is encountered and returning the nth square free number.
Following is the implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int squareFree( int n)
{
int cnt = 0;
for ( int i=1;; i++)
{
bool isSqFree = true ;
for ( int j=2; j*j<=i; j++)
{
if (i % (j*j) == 0)
{
isSqFree = false ;
break ;
}
}
if (isSqFree == true )
{
cnt++;
if (cnt == n)
return i;
}
}
return 0;
}
int main()
{
int n = 10;
cout << squareFree(n) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int squareFree( int n)
{
int cnt = 0 ;
for ( int i = 1 ; ; i++) {
boolean isSqFree = true ;
for ( int j = 2 ; j * j <= i; j++)
{
if (i % (j * j) == 0 ) {
isSqFree = false ;
break ;
}
}
if (isSqFree == true ) {
cnt++;
if (cnt == n)
return i;
}
}
}
public static void main(String[] args) {
int n = 10 ;
System.out.println( "" + squareFree(n));
}
}
|
Python3
def squareFree(n):
cnt = 0 ;
i = 1 ;
while ( True ):
isSqFree = True ;
j = 2 ;
while (j * j < = i):
if (i % (j * j) = = 0 ):
isSqFree = False ;
break ;
j + = 1 ;
if (isSqFree = = True ):
cnt + = 1 ;
if (cnt = = n):
return i;
i + = 1 ;
return 0 ;
n = 10 ;
print (squareFree(n));
|
C#
using System;
class GFG {
public static int squareFree( int n)
{
int cnt = 0;
for ( int i = 1; ; i++)
{
bool isSqFree = true ;
for ( int j = 2; j * j <= i; j++)
{
if (i % (j * j) == 0) {
isSqFree = false ;
break ;
}
}
if (isSqFree == true ) {
cnt++;
if (cnt == n)
return i;
}
}
}
public static void Main()
{
int n = 10;
Console.Write( "" + squareFree(n));
}
}
|
PHP
<?php
function squareFree( $n )
{
$cnt = 0;
for ( $i = 1; ; $i ++)
{
$isSqFree = true;
for ( $j = 2; $j * $j <= $i ; $j ++)
{
if ( $i % ( $j * $j ) == 0)
{
$isSqFree = false;
break ;
}
}
if ( $isSqFree == true)
{
$cnt ++;
if ( $cnt == $n )
return $i ;
}
}
return 0;
}
$n = 10;
echo (squareFree( $n ));
?>
|
Javascript
<script>
function squareFree(n)
{
let cnt = 0;
for (let i = 1; ; i++) {
let isSqFree = true ;
for (let j = 2; j * j <= i; j++)
{
if (i % (j * j) == 0) {
isSqFree = false ;
break ;
}
}
if (isSqFree == true ) {
cnt++;
if (cnt == n)
return i;
}
}
}
let n = 10;
document.write( "" + squareFree(n));
</script>
|
Output:
14
Time Complexity: O(n3/2)
Auxiliary Space: O(1)
Method 2 (Better approach):
Idea is to count square free numbers less than or equal to upper limit ‘k’ and then apply binary search to find n-th square free number. First, we calculate count of square numbers (numbers with squares as factors) upto ‘k’ and then subtracting that count from total numbers to get count of square free numbers upto ‘k’.
Explanation:
- If any integer has a perfect square as factor, then it is guaranteed that it has a square of prime as a factor too. So we need to count the integers less than or equal to ‘k’ which have square of primes as a factor.
For example, find number of integers who have either 4 or 9 as a factor upto ‘k’. It can done using Inclusion–exclusion principle. Using Inclusion–exclusion principle, total number of integers are [k/4] + [k/9] -[k/36] where [] is greatest integer function.
- Recursively apply inclusion and exclusion till the value of greatest integer becomes zero. This step will return count of numbers with squares as factors.
- Apply binary search to find the nth square free number.
Following is the implementation of above algorithm:
C++
#include<bits/stdc++.h>
using namespace std;
const int MAX_PRIME = 100000;
const int MAX_RES = 2000000000l;
void SieveOfEratosthenes(vector< long long > &a)
{
bool prime[MAX_PRIME + 1];
memset (prime, true , sizeof (prime));
for ( long long p=2; p*p<=MAX_PRIME; p++)
{
if (prime[p] == true )
{
for ( long long i=p*2; i<=MAX_PRIME; i += p)
prime[i] = false ;
}
}
for ( long long p=2; p<=MAX_PRIME; p++)
if (prime[p])
a.push_back(p);
}
long long countSquares( long long i, long long cur,
long long k, vector< long long > &a)
{
long long square = a[i]*a[i];
long long newCur = square*cur;
if (newCur > k)
return 0;
long long cnt = k/(newCur);
cnt += countSquares(i+1, cur, k, a);
cnt -= countSquares(i+1, newCur, k, a);
return cnt;
}
long long squareFree( long long n)
{
vector < long long > a;
SieveOfEratosthenes(a);
long long low = 1;
long long high = MAX_RES;
while (low < high)
{
long long mid = low + (high - low)/2;
long long c = mid - countSquares(0, 1, mid, a);
if (c < n)
low = mid+1;
else
high = mid;
}
return low;
}
int main()
{
int n = 10;
cout << squareFree(n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX_PRIME = 100000 ;
static int MAX_RES = 2000000000 ;
static void SieveOfEratosthenes(Vector<Long> a)
{
boolean prime[] = new boolean [MAX_PRIME + 1 ];
Arrays.fill(prime, true );
for ( int p = 2 ; p * p <= MAX_PRIME; p++)
{
if (prime[p] == true )
{
for ( int i = p * 2 ; i <= MAX_PRIME; i += p)
prime[i] = false ;
}
}
for ( int p = 2 ; p <= MAX_PRIME; p++)
if (prime[p])
a.add(( long )p);
}
static long countSquares( long i, long cur,
long k, Vector<Long> a)
{
long square = a.get(( int ) i)*a.get(( int )(i));
long newCur = square*cur;
if (newCur > k)
return 0 ;
long cnt = k/(newCur);
cnt += countSquares(i + 1 , cur, k, a);
cnt -= countSquares(i + 1 , newCur, k, a);
return cnt;
}
static long squareFree( long n)
{
Vector <Long> a = new Vector<>();
SieveOfEratosthenes(a);
long low = 1 ;
long high = MAX_RES;
while (low < high)
{
long mid = low + (high - low)/ 2 ;
long c = mid - countSquares( 0 , 1 , mid, a);
if (c < n)
low = mid+ 1 ;
else
high = mid;
}
return low;
}
public static void main(String[] args)
{
int n = 10 ;
System.out.println(squareFree(n));
}
}
|
Python3
import sys
sys.setrecursionlimit( 15000 )
MAX_PRIME = 100000 ;
MAX_RES = 2000000000
def SieveOfEratosthenes(a):
prime = [ True for i in range (MAX_PRIME + 1 )];
p = 2
while (p * p < = MAX_PRIME):
if (prime[p] = = True ):
for i in range (p * 2 , MAX_PRIME + 1 , p):
prime[i] = False ;
p + = 1
for p in range ( 2 , MAX_PRIME + 1 ):
if (prime[p]):
a.append(p);
return a
def countSquares(i, cur, k, a):
square = a[i] * a[i];
newCur = square * cur;
if (newCur > k):
return 0 , a;
cnt = k / / (newCur);
tmp, a = countSquares(i + 1 , cur, k, a);
cnt + = tmp
tmp, a = countSquares(i + 1 , newCur, k, a);
cnt - = tmp
return cnt,a;
def squareFree(n):
a = SieveOfEratosthenes([]);
low = 1 ;
high = MAX_RES;
while (low < high):
mid = low + (high - low) / / 2 ;
c,a = countSquares( 0 , 1 , mid, a);
c = mid - c
if (c < n):
low = mid + 1 ;
else :
high = mid;
return low;
if __name__ = = '__main__' :
n = 10 ;
print (squareFree(n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX_PRIME = 100000;
static int MAX_RES = 2000000000;
static void SieveOfEratosthenes(List< long > a)
{
bool []prime = new bool [MAX_PRIME + 1];
for ( int i = 0; i < MAX_PRIME + 1; i++)
prime[i] = true ;
for ( int p = 2; p * p <= MAX_PRIME; p++)
{
if (prime[p] == true )
{
for ( int i = p * 2; i <= MAX_PRIME; i += p)
prime[i] = false ;
}
}
for ( int p = 2; p <= MAX_PRIME; p++)
if (prime[p])
a.Add(( long )p);
}
static long countSquares( long i, long cur,
long k, List< long > a)
{
long square = a[( int ) i]*a[( int )(i)];
long newCur = square * cur;
if (newCur > k)
return 0;
long cnt = k/(newCur);
cnt += countSquares(i + 1, cur, k, a);
cnt -= countSquares(i + 1, newCur, k, a);
return cnt;
}
static long squareFree( long n)
{
List< long > a = new List< long >();
SieveOfEratosthenes(a);
long low = 1;
long high = MAX_RES;
while (low < high)
{
long mid = low + (high - low)/2;
long c = mid - countSquares(0, 1, mid, a);
if (c < n)
low = mid + 1;
else
high = mid;
}
return low;
}
public static void Main()
{
int n = 10;
Console.WriteLine(squareFree(n));
}
}
|
Javascript
<script>
let MAX_PRIME = 100000;
let MAX_RES = 2000000000;
function SieveOfEratosthenes(a)
{
let prime = new Array(MAX_PRIME + 1);
for (let i=0;i<(MAX_PRIME + 1);i++)
{
prime[i]= true ;
}
for (let p = 2; p * p <= MAX_PRIME; p++)
{
if (prime[p] == true )
{
for (let i = p * 2; i <= MAX_PRIME; i += p)
prime[i] = false ;
}
}
for (let p = 2; p <= MAX_PRIME; p++)
if (prime[p])
a.push(p);
}
function countSquares(i,cur,k,a)
{
let square = a[i]*a[i];
let newCur = square*cur;
if (newCur > k)
return 0;
let cnt = Math.floor(k/(newCur));
cnt += countSquares(i + 1, cur, k, a);
cnt -= countSquares(i + 1, newCur, k, a);
return cnt;
}
function squareFree(n)
{
let a = [];
SieveOfEratosthenes(a);
let low = 1;
let high = MAX_RES;
while (low < high)
{
let mid = low + Math.floor((high - low)/2);
let c = mid - countSquares(0, 1, mid, a);
if (c < n)
low = mid+1;
else
high = mid;
}
return low;
}
let n = 10;
document.write(squareFree(n));
</script>
|
Output:
14
Time Complexity: O(MAX_PRIME * log(log(MAX_PRIME))) + O(sqrt(MAX_RES)) * log(MAX_RES))
Auxiliary Space: O(MAX_PRIME + sqrt(MAX_RES))
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
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!
Last Updated :
20 Mar, 2023
Like Article
Save Article