Given an array of positive integers arr[], the task is to count the minimum factor jumps required to reach the end of an array. From any particular index i, the jump can be made only for K indices where K is a factor of arr[i].
Examples:
Input: arr[] = {2, 8, 16, 55, 99, 100}
Output: 2
Explanation:
The optimal jumps are:
a) Start from 2.
b) Since factors of 2 are [1, 2]. So only 1 or 2 index jumps are available. Therefore, jump 1 index to reach 8.
c) Since factors of 8 are [1, 2, 4, 8]. So only 1, 2, 4 or 8 index jumps are available. Therefore, they jumped 4 indices to reach 100.
d) We have reached the end, so no more jumps are required.
So, 2 jumps were required.
Input: arr[] = {2, 4, 6}
Output: 1
Approach: This problem can be solved using Recursion.
- Firstly, we need to precompute the factors of every number from 1 to 1000000, so that we can get different choices of jumps in O(1) time.
- Then, recursively calculate the minimum jumps required to reach the end of the array and print it.
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors[100005];
void precompute()
{
for ( int i = 1; i <= 100000; i++) {
for ( int j = i; j <= 100000; j += i) {
factors[j].push_back(i);
}
}
}
int solve( int arr[], int k, int n)
{
if (k == n - 1) {
return 0;
}
if (k >= n) {
return INT_MAX;
}
int ans = INT_MAX;
for ( auto j : factors[arr[k]]) {
int res = solve(arr, k + j, n);
if (res != INT_MAX) {
ans = min(ans, res + 1);
}
}
return ans;
}
int main()
{
precompute();
int arr[] = { 2, 8, 16, 55, 99, 100 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << solve(arr, 0, n);
}
|
Java
import java.util.*;
public class GFG{
static Vector<Integer> []factors =
new Vector[ 100005 ];
static void precompute()
{
for ( int i = 0 ; i < factors.length; i++)
factors[i] = new Vector<Integer>();
for ( int i = 1 ; i <= 100000 ; i++)
{
for ( int j = i; j <= 100000 ; j += i)
{
factors[j].add(i);
}
}
}
static int solve( int arr[],
int k, int n)
{
if (k == n - 1 )
{
return 0 ;
}
if (k >= n)
{
return Integer.MAX_VALUE;
}
int ans = Integer.MAX_VALUE;
for ( int j : factors[arr[k]])
{
int res = solve(arr, k + j, n);
if (res != Integer.MAX_VALUE)
{
ans = Math.min(ans, res + 1 );
}
}
return ans;
}
public static void main(String[] args)
{
precompute();
int arr[] = { 2 , 8 , 16 ,
55 , 99 , 100 };
int n = arr.length;
System.out.print(solve(arr, 0 , n));
}
}
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > []factors =
new List< int >[100005];
static void precompute()
{
for ( int i = 0;
i < factors.Length; i++)
factors[i] = new List< int >();
for ( int i = 1; i <= 100000; i++)
{
for ( int j = i;
j <= 100000; j += i)
{
factors[j].Add(i);
}
}
}
static int solve( int []arr,
int k, int n)
{
if (k == n - 1)
{
return 0;
}
if (k >= n)
{
return int .MaxValue;
}
int ans = int .MaxValue;
foreach ( int j in factors[arr[k]])
{
int res = solve(arr, k + j, n);
if (res != int .MaxValue)
{
ans = Math.Min(ans, res + 1);
}
}
return ans;
}
public static void Main(String[] args)
{
precompute();
int []arr = {2, 8, 16,
55, 99, 100};
int n = arr.Length;
Console.Write(solve(arr, 0, n));
}
}
|
Python
factors = [[] for i in range ( 100005 )]
def precompute():
for i in range ( 1 , 100001 ):
for j in range (i, 100001 , i):
factors[j].append(i)
def solve(arr, k, n):
if (k = = n - 1 ):
return 0
if (k > = n):
return 1000000000
ans = 1000000000
for j in factors[arr[k]]:
res = solve(arr, k + j, n)
if (res ! = 1000000000 ):
ans = min (ans, res + 1 )
return ans
if __name__ = = '__main__' :
precompute()
arr = [ 2 , 8 , 16 , 55 , 99 , 100 ]
n = len (arr)
print (solve(arr, 0 , n))
|
Javascript
<script>
let factors = new Array();
for (let i = 0; i < 100005; i++) {
factors.push( new Array());
}
function precompute() {
for (let i = 1; i <= 100000; i++) {
for (let j = i; j <= 100000; j += i) {
factors[j].push(i);
}
}
}
function solve(arr, k, n) {
if (k == n - 1) {
return 0;
}
if (k >= n) {
return Number.MAX_SAFE_INTEGER;
}
let ans = Number.MAX_SAFE_INTEGER;
for (let j of factors[arr[k]]) {
let res = solve(arr, k + j, n);
if (res != Number.MAX_SAFE_INTEGER) {
ans = Math.min(ans, res + 1);
}
}
return ans;
}
precompute();
let arr = [2, 8, 16, 55, 99, 100];
let n = arr.length;
document.write(solve(arr, 0, n));
</script>
|
Time Complexity: O(100005*2N)
Auxiliary Space: O(100005)
Another Approach: Dynamic Programming using Memoization.
- Firstly, we need to precompute the factors of every number from 1 to 1000000, so that we can get different choices of jumps in O(1) time.
- Then, let dp[i] be the minimum jump required to reach i, we need to find dp[n-1].
- So, the recurrence relation becomes:
![Rendered by QuickLaTeX.com dp[i] = min(dp[i], 1 + solve(i+j))](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-194368907ec895986c58c129a7b4f30c_l3.png)
where j is one of the factors of arr[i] & solve() is the recursive function
- Find the minimum jumps using this recurrence relation and print it.
Below is the recursive implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors[100005];
int dp[100005];
void precompute()
{
for ( int i = 1; i <= 100000; i++) {
for ( int j = i; j <= 100000; j += i) {
factors[j].push_back(i);
}
}
}
int solve( int arr[], int k, int n)
{
if (k == n - 1) {
return 0;
}
if (k >= n) {
return INT_MAX;
}
if (dp[k]) {
return dp[k];
}
int ans = INT_MAX;
for ( auto j : factors[arr[k]]) {
int res = solve(arr, k + j, n);
if (res != INT_MAX) {
ans = min(ans, res + 1);
}
}
return dp[k] = ans;
}
int main()
{
precompute();
int arr[] = { 2, 8, 16, 55, 99, 100 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << solve(arr, 0, n);
}
|
Java
import java.util.*;
class GFG{
static Vector<Integer> []factors =
new Vector[ 100005 ];
static int []dp = new int [ 100005 ];
static void precompute()
{
for ( int i = 0 ; i < factors.length; i++)
factors[i] = new Vector<Integer>();
for ( int i = 1 ; i <= 100000 ; i++)
{
for ( int j = i; j <= 100000 ; j += i)
{
factors[j].add(i);
}
}
}
static int solve( int arr[],
int k, int n)
{
if (k == n - 1 )
{
return 0 ;
}
if (k >= n)
{
return Integer.MAX_VALUE;
}
if (dp[k] != 0 )
{
return dp[k];
}
int ans = Integer.MAX_VALUE;
for ( int j : factors[arr[k]])
{
int res = solve(arr, k + j, n);
if (res != Integer.MAX_VALUE)
{
ans = Math.min(ans, res + 1 );
}
}
return dp[k] = ans;
}
public static void main(String[] args)
{
precompute();
int arr[] = { 2 , 8 , 16 ,
55 , 99 , 100 };
int n = arr.length;
System.out.print(solve(arr, 0 , n));
}
}
|
Python3
factors = [[] for i in range ( 100005 )];
dp = [ 0 for i in range ( 100005 )];
def precompute():
for i in range ( 1 , 100001 ):
for j in range (i, 100001 , i):
factors[j].append(i);
def solve(arr, k, n):
if (k = = n - 1 ):
return 0 ;
if (k > = n):
return 1000000000
if (dp[k]):
return dp[k];
ans = 1000000000
for j in factors[arr[k]]:
res = solve(arr, k + j, n);
if (res ! = 1000000000 ):
ans = min (ans, res + 1 );
dp[k] = ans;
return ans
if __name__ = = '__main__' :
precompute()
arr = [ 2 , 8 , 16 , 55 , 99 , 100 ]
n = len (arr)
print (solve(arr, 0 , n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > []factors =
new List< int >[100005];
static int []dp = new int [100005];
static void precompute()
{
for ( int i = 0;
i < factors.Length; i++)
factors[i] = new List< int >();
for ( int i = 1; i <= 100000; i++)
{
for ( int j = i;
j <= 100000; j += i)
{
factors[j].Add(i);
}
}
}
static int solve( int []arr,
int k, int n)
{
if (k == n - 1)
{
return 0;
}
if (k >= n)
{
return int .MaxValue;
}
if (dp[k] != 0)
{
return dp[k];
}
int ans = int .MaxValue;
foreach ( int j in factors[arr[k]])
{
int res = solve(arr, k + j, n);
if (res != int .MaxValue)
{
ans = Math.Min(ans, res + 1);
}
}
return dp[k] = ans;
}
public static void Main(String[] args)
{
precompute();
int []arr = {2, 8, 16,
55, 99, 100};
int n = arr.Length;
Console.Write(solve(arr, 0, n));
}
}
|
Javascript
<script>
let factors = new Array();
let dp = new Array(100005);
for (let i = 0; i < 100005; i++) {
factors.push( new Array());
}
function precompute() {
for (let i = 1; i <= 100000; i++) {
for (let j = i; j <= 100000; j += i) {
factors[j].push(i);
}
}
}
function solve(arr, k, n) {
if (k == n - 1) {
return 0;
}
if (k >= n) {
return Number.MAX_SAFE_INTEGER;
}
if (dp[k]) {
return dp[k];
}
let ans = Number.MAX_SAFE_INTEGER;
for (let j of factors[arr[k]]) {
let res = solve(arr, k + j, n);
if (res != Number.MAX_SAFE_INTEGER) {
ans = Math.min(ans, res + 1);
}
}
return dp[k] = ans;
}
precompute();
let arr = [2, 8, 16, 55, 99, 100];
let n = arr.length;
document.write(solve(arr, 0, n));
</script>
|
Time Complexity: O(100000*N)
Auxiliary Space: O(100005)
Given below is the Iterative Bottom-Up Approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors[100005];
int dp[100005];
void precompute()
{
for ( int i = 1; i <= 100000; i++) {
for ( int j = i; j <= 100000; j += i)
factors[j].push_back(i);
}
}
int solve( int arr[], int n)
{
for ( int i = 0; i <= 100005; i++) {
dp[i] = INT_MAX;
}
dp[0] = 0;
for ( int i = 0; i < n; i++) {
for ( auto j : factors[arr[i]]) {
if (i + j < n)
dp[i + j] = min(dp[i + j], 1 + dp[i]);
}
}
return dp[n - 1];
}
int main()
{
precompute();
int arr[] = { 2, 8, 16, 55, 99, 100 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << solve(arr, n);
}
|
Java
import java.util.*;
class GFG{
@SuppressWarnings ( "unchecked" )
static Vector<Integer> []factors = new Vector[ 100005 ];
static int []dp = new int [ 100005 ];
static void precompute()
{
for ( int i = 1 ; i <= 100000 ; i++)
{
for ( int j = i; j <= 100000 ; j += i)
factors[j].add(i);
}
}
static int solve( int arr[], int n)
{
for ( int i = 0 ; i < 100005 ; i++)
{
dp[i] = Integer.MAX_VALUE;
}
dp[ 0 ] = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j : factors[arr[i]])
{
if (i + j < n)
dp[i + j] = Math.min(dp[i + j],
1 + dp[i]);
}
}
return dp[n - 1 ];
}
public static void main(String[] args)
{
for ( int i = 0 ; i < factors.length; i++)
factors[i] = new Vector<Integer>();
precompute();
int arr[] = { 2 , 8 , 16 , 55 , 99 , 100 };
int n = arr.length;
System.out.print(solve(arr, n));
}
}
|
Python3
factors = [[] for i in range ( 100005 )];
dp = [ 1000000000 for i in range ( 100005 )];
def precompute():
for i in range ( 1 , 100001 ):
for j in range (i, 100001 , i):
factors[j].append(i);
def solve(arr, n):
dp[ 0 ] = 0 ;
for i in range (n):
for j in factors[arr[i]]:
if (i + j < n):
dp[i + j] = min (dp[i + j], 1 + dp[i]);
return dp[n - 1 ];
if __name__ = = '__main__' :
precompute();
arr = [ 2 , 8 , 16 , 55 , 99 , 100 ]
n = len (arr)
print (solve(arr,n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List<List< int >> factors = new List<List< int >>();
static int [] dp;
static void precompute()
{
for ( int i = 1; i <= 100000; i++)
{
for ( int j = i; j <= 100000; j += i)
factors[j].Add(i);
}
}
static int solve( int [] arr, int n)
{
for ( int i = 0; i < 100005; i++)
{
dp[i] = int .MaxValue;
}
dp[0] = 0;
for ( int i = 0; i < n; i++)
{
foreach ( int j in factors[arr[i]])
{
if (i + j < n)
dp[i + j] = Math.Min(dp[i + j],
1 + dp[i]);
}
}
return dp[n - 1];
}
static public void Main ()
{
for ( int i = 0; i < 100005; i++)
factors.Add( new List< int >());
dp = new int [100005];
precompute();
int [] arr = { 2, 8, 16, 55, 99, 100 };
int n = arr.Length;
Console.Write(solve(arr, n));
}
}
|
Javascript
<script>
var factors = Array.from(Array(100005), ()=>Array());
var dp = Array(100005);
function precompute()
{
for ( var i = 1; i <= 100000; i++) {
for ( var j = i; j <= 100000; j += i)
factors[j].push(i);
}
}
function solve(arr, n)
{
for ( var i = 0; i <= 100005; i++) {
dp[i] = 1000000000;
}
dp[0] = 0;
for ( var i = 0; i < n; i++) {
for ( var j of factors[arr[i]]) {
if (i + j < n)
dp[i + j] = Math.min(dp[i + j], 1 + dp[i]);
}
}
return dp[n - 1];
}
precompute();
var arr = [2, 8, 16, 55, 99, 100];
var n = arr.length
document.write( solve(arr, n));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(100005)