Minimum steps to reach end of array under constraints
Given an array containing one digit numbers only, assuming we are standing at first index, we need to reach to end of array using minimum number of steps where in one step, we can jump to neighbor indices or can jump to a position with same value.
In other words, if we are at index i, then in one step you can reach to, arr[i-1] or arr[i+1] or arr[K] such that arr[K] = arr[i] (value of arr[K] is same as arr[i])
Examples:
Input : arr[] = {5, 4, 2, 5, 0}
Output : 2
Explanation : Total 2 step required.
We start from 5(0), in first step jump to next 5
and in second step we move to value 0 (End of arr[]).
Input : arr[] = [0, 1, 2, 3, 4, 5, 6, 7, 5, 4,
3, 6, 0, 1, 2, 3, 4, 5, 7]
Output : 5
Explanation : Total 5 step required.
0(0) -> 0(12) -> 6(11) -> 6(6) -> 7(7) ->
(18)
(inside parenthesis indices are shown)
This problem can be solved using BFS. We can consider the given array as unweighted graph where every vertex has two edges to next and previous array elements and more edges to array elements with same values. Now for fast processing of third type of edges, we keep 10 vectors which store all indices where digits 0 to 9 are present. In above example, vector corresponding to 0 will store [0, 12], 2 indices where 0 has occurred in given array.
Another Boolean array is used, so that we don’t visit same index more than once. As we are using BFS and BFS proceeds level by level, optimal minimum steps are guaranteed.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int getMinStepToReachEnd( int arr[], int N)
{
bool visit[N];
int distance[N];
vector< int > digit[10];
memset (visit, false , sizeof (visit));
for ( int i = 1; i < N; i++)
digit[arr[i]].push_back(i);
distance[0] = 0;
visit[0] = true ;
queue< int > q;
q.push(0);
while (!q.empty())
{
int idx = q.front(); q.pop();
if (idx == N-1)
break ;
int d = arr[idx];
for ( int i = 0; i<digit[d].size(); i++)
{
int nextidx = digit[d][i];
if (!visit[nextidx])
{
visit[nextidx] = true ;
q.push(nextidx);
distance[nextidx] = distance[idx] + 1;
}
}
digit[d].clear();
if (idx-1 >= 0 && !visit[idx - 1])
{
visit[idx - 1] = true ;
q.push(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true ;
q.push(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
return distance[N - 1];
}
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 5,
4, 3, 6, 0, 1, 2, 3, 4, 5, 7};
int N = sizeof (arr) / sizeof ( int );
cout << getMinStepToReachEnd(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int getMinStepToReachEnd( int arr[],
int N)
{
boolean []visit = new boolean [N];
int []distance = new int [N];
Vector<Integer> []digit = new Vector[ 10 ];
for ( int i = 0 ; i < 10 ; i++)
digit[i] = new Vector<>();
for ( int i = 0 ; i < N; i++)
visit[i] = false ;
for ( int i = 1 ; i < N; i++)
digit[arr[i]].add(i);
distance[ 0 ] = 0 ;
visit[ 0 ] = true ;
Queue<Integer> q = new LinkedList<>();
q.add( 0 );
while (!q.isEmpty())
{
int idx = q.peek();
q.remove();
if (idx == N - 1 )
break ;
int d = arr[idx];
for ( int i = 0 ; i < digit[d].size(); i++)
{
int nextidx = digit[d].get(i);
if (!visit[nextidx])
{
visit[nextidx] = true ;
q.add(nextidx);
distance[nextidx] = distance[idx] + 1 ;
}
}
digit[d].clear();
if (idx - 1 >= 0 && !visit[idx - 1 ])
{
visit[idx - 1 ] = true ;
q.add(idx - 1 );
distance[idx - 1 ] = distance[idx] + 1 ;
}
if (idx + 1 < N && !visit[idx + 1 ])
{
visit[idx + 1 ] = true ;
q.add(idx + 1 );
distance[idx + 1 ] = distance[idx] + 1 ;
}
}
return distance[N - 1 ];
}
public static void main(String []args)
{
int arr[] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 5 ,
4 , 3 , 6 , 0 , 1 , 2 , 3 , 4 , 5 , 7 };
int N = arr.length;
System.out.println(getMinStepToReachEnd(arr, N));
}
}
|
Python3
def getMinStepToReachEnd(arr,N):
visit = [ False for i in range (N)]
distance = [ 0 for i in range (N)]
digit = [[ 0 for i in range (N)] for j in range ( 10 )]
for i in range ( 1 ,N):
digit[arr[i]].append(i)
distance[ 0 ] = 0
visit[ 0 ] = True
q = []
q.append( 0 )
while ( len (q)> 0 ):
idx = q[ 0 ]
q.remove(q[ 0 ])
if (idx = = N - 1 ):
break
d = arr[idx]
for i in range ( len (digit[d])):
nextidx = digit[d][i]
if (visit[nextidx] = = False ):
visit[nextidx] = True
q.append(nextidx)
distance[nextidx] = distance[idx] + 1
if (idx - 1 > = 0 and visit[idx - 1 ] = = False ):
visit[idx - 1 ] = True
q.append(idx - 1 )
distance[idx - 1 ] = distance[idx] + 1
if (idx + 1 < N and visit[idx + 1 ] = = False ):
visit[idx + 1 ] = True
q.append(idx + 1 )
distance[idx + 1 ] = distance[idx] + 1
return distance[N - 1 ]
if __name__ = = '__main__' :
arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 5 , 4 , 3 , 6 , 0 , 1 , 2 , 3 , 4 , 5 , 7 ]
N = len (arr)
print (getMinStepToReachEnd(arr, N))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int getMinStepToReachEnd( int []arr,
int N)
{
bool []visit = new bool [N];
int []distance = new int [N];
List< int > []digit = new List< int >[10];
for ( int i = 0; i < 10; i++)
digit[i] = new List< int >();
for ( int i = 0; i < N; i++)
visit[i] = false ;
for ( int i = 1; i < N; i++)
digit[arr[i]].Add(i);
distance[0] = 0;
visit[0] = true ;
Queue< int > q = new Queue< int >();
q.Enqueue(0);
while (q.Count != 0)
{
int idx = q.Peek();
q.Dequeue();
if (idx == N - 1)
break ;
int d = arr[idx];
for ( int i = 0; i < digit[d].Count; i++)
{
int nextidx = digit[d][i];
if (!visit[nextidx])
{
visit[nextidx] = true ;
q.Enqueue(nextidx);
distance[nextidx] = distance[idx] + 1;
}
}
digit[d].Clear();
if (idx - 1 >= 0 && !visit[idx - 1])
{
visit[idx - 1] = true ;
q.Enqueue(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true ;
q.Enqueue(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
return distance[N - 1];
}
public static void Main(String []args)
{
int []arr = {0, 1, 2, 3, 4, 5, 6, 7, 5,
4, 3, 6, 0, 1, 2, 3, 4, 5, 7};
int N = arr.Length;
Console.WriteLine(getMinStepToReachEnd(arr, N));
}
}
|
Javascript
<script>
function getMinStepToReachEnd(arr,N)
{
let visit = new Array(N);
let distance = new Array(N);
let digit = new Array(10);
for (let i = 0; i < 10; i++)
digit[i] = [];
for (let i = 0; i < N; i++)
visit[i] = false ;
for (let i = 1; i < N; i++)
digit[arr[i]].push(i);
distance[0] = 0;
visit[0] = true ;
let q = [];
q.push(0);
while (q.length!=0)
{
let idx = q.shift();
if (idx == N - 1)
break ;
let d = arr[idx];
for (let i = 0; i < digit[d].length; i++)
{
let nextidx = digit[d][i];
if (!visit[nextidx])
{
visit[nextidx] = true ;
q.push(nextidx);
distance[nextidx] = distance[idx] + 1;
}
}
digit[d]=[];
if (idx - 1 >= 0 && !visit[idx - 1])
{
visit[idx - 1] = true ;
q.push(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true ;
q.push(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
return distance[N - 1];
}
let arr=[0, 1, 2, 3, 4, 5, 6, 7, 5,
4, 3, 6, 0, 1, 2, 3, 4, 5, 7];
let N = arr.length;
document.write(getMinStepToReachEnd(arr, N));
</script>
|
Time Complexity: O(N), where N is the number of elements in the array.
Space Complexity: O(N), where N is the number of elements in the array. We are using a distance and visit array of size N and a queue of size N to store the indices of the array.
Last Updated :
18 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...