Minimum jumps to same value or adjacent to reach end of Array
Last Updated :
02 Dec, 2022
Given an array arr[] of size N, the task is to find the minimum number of jumps to reach the last index of the array starting from index 0. In one jump you can move from current index i to index j, if arr[i] = arr[j] and i != j or you can jump to (i + 1) or (i – 1).
Note: You can not jump outside of the array at any time.
Examples:
Input: arr = {100, -23, -23, 404, 100, 23, 23, 23, 3, 404}
Output: 3
Explanation: Valid jump indices are 0 -> 4 -> 3 -> 9.
Input: arr = {7, 6, 9, 6, 9, 6, 9, 7}
Output: 1
An approach using BFS:
Here consider the elements which are at (i + 1), (i – 1), and all elements similar to arr[i] and insert them into a queue to perform BFS. Repeat the BFS in this manner and keep the track of level. When the end of array is reached return the level value.
Follow the steps below to implement the above idea:
- Initialize a map for mapping elements with the indices of their occurrence.
- Initialize a queue and an array visited[] to keep track of the elements that are visited.
- Push starting element into the queue and mark it as visited
- Initialize a variable count for counting the minimum number of valid jumps to reach the last index
- Do the following while the queue size is greater than 0:
- Iterate on all the elements of the queue
- Fetch the front element and pop out from the queue
- Check if we reach the last index or not
- If true, then return the count
- Check if curr + 1 is a valid position to visit or not
- If true, push curr + 1 into the queue and mark it as visited
- Check if curr – 1 is a valid position to visit or not
- If true, push curr – 1 into the queue and mark it as visited
- Now, Iterate over all the elements that are similar to curr
- Check if the child is in a valid position to visit or not
- If true, push the child into the queue and mark it as visited
- Erase all the occurrences of curr from the map because we already considered these elements for a valid jump in the above step
- Increment the count of jump
- Finally, return the count.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int minimizeJumps(vector< int >& arr)
{
int n = arr.size();
unordered_map< int , vector< int > > unmap;
for ( int i = 0; i < n; i++) {
unmap[arr[i]].push_back(i);
}
queue< int > q;
vector< bool > visited(n, false );
q.push(0);
visited[0] = true ;
int count = 0;
while (q.size() > 0) {
int size = q.size();
for ( int i = 0; i < size; i++) {
int curr = q.front();
q.pop();
if (curr == n - 1) {
return count;
}
if (curr + 1 < n
&& visited[curr + 1] == false ) {
q.push(curr + 1);
visited[curr + 1] = true ;
}
if (curr - 1 >= 0
&& visited[curr - 1] == false ) {
q.push(curr - 1);
visited[curr - 1] = true ;
}
for ( auto child : unmap[arr[curr]]) {
if (curr == child)
continue ;
if (visited[child] == false ) {
q.push(child);
visited[child] = true ;
}
}
unmap.erase(arr[curr]);
}
count++;
}
return count;
}
int main()
{
vector< int > arr
= { 100, -23, -23, 404, 100, 23, 23, 23, 3, 404 };
cout << minimizeJumps(arr);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int minimizeJumps( int [] arr)
{
int n = arr.length;
HashMap<Integer, List<Integer> > unmap
= new HashMap<>();
for ( int i = 0 ; i < n; i++) {
if (unmap.containsKey(arr[i])) {
unmap.get(arr[i]).add(i);
}
else {
List<Integer> temp = new ArrayList<>();
temp.add(i);
unmap.put(arr[i], temp);
}
}
Queue<Integer> q = new LinkedList<>();
boolean [] visited = new boolean [n];
Arrays.fill(visited, false );
q.add( 0 );
visited[ 0 ] = true ;
int count = 0 ;
while (q.size() > 0 ) {
int size = q.size();
for ( int i = 0 ; i < size; i++) {
int curr = q.poll();
if (curr == n - 1 ) {
return count / 2 ;
}
if (curr + 1 < n
&& visited[curr + 1 ] == false ) {
q.add(curr + 1 );
visited[curr + 1 ] = true ;
}
if (curr - 1 >= 0
&& visited[curr - 1 ] == false ) {
q.add(curr - 1 );
visited[curr - 1 ] = true ;
}
if (unmap.containsKey(arr[i])) {
for ( int j = 0 ;
j < unmap.get(arr[curr]).size();
j++) {
int child
= unmap.get(arr[curr]).get(j);
if (curr == child) {
continue ;
}
if (visited[child] == false ) {
q.add(child);
visited[child] = true ;
}
}
}
unmap.remove(arr[curr]);
}
count++;
}
return count / 2 ;
}
public static void main(String[] args)
{
int [] arr = { 100 , - 23 , - 23 , 404 , 100 ,
23 , 23 , 23 , 3 , 404 };
System.out.print(minimizeJumps(arr));
}
}
|
Python3
def minimizeJumps(arr):
n = len (arr)
unmap = {}
for i in range (n):
if arr[i] in unmap:
unmap.get(arr[i]).append(i)
else :
unmap.update({arr[i]:[i]})
q = []
visited = [ False ] * n
q.append( 0 )
visited[ 0 ] = True
count = 0
while ( len (q) > 0 ):
size = len (q)
for i in range (size):
curr = q[ 0 ]
q.pop( 0 )
if (curr = = n - 1 ):
return count / / 2
if (curr + 1 < n and visited[curr + 1 ] = = False ):
q.append(curr + 1 )
visited[curr + 1 ] = True
if (curr - 1 > = 0 and visited[curr - 1 ] = = False ):
q.append(curr - 1 )
visited[curr - 1 ] = True
if arr[i] in unmap:
for j in range ( len (unmap[arr[curr]])):
child = unmap.get(arr[curr])[j]
if (curr = = child):
continue
if (visited[child] = = False ):
q.append(child)
visited[child] = True
if arr[curr] in unmap:
unmap.pop(arr[curr])
count = count + 1
return count / / 2
arr = [ 100 , - 23 , - 23 , 404 , 100 , 23 , 23 , 23 , 3 , 404 ]
print (minimizeJumps(arr))
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static int minimizeJumps( int [] arr)
{
int n = arr.Length;
Dictionary< int ,List< int >> unmap = new Dictionary< int ,List< int >>();
for ( int i = 0; i < n; i++) {
if (unmap.ContainsKey(arr[i])) {
unmap[arr[i]].Add(i);
}
else {
List< int > temp = new List< int >();
temp.Add(i);
unmap.Add(arr[i],temp);
}
}
List< int > q = new List< int >();
bool [] visited = new bool [n];
for ( int i=0;i<n;i++)
{
visited[i]= false ;
}
q.Add(0);
visited[0] = true ;
int count = 0;
while (q.Count > 0) {
int size = q.Count;
for ( int i = 0; i < size; i++) {
int curr = q[0];
q.RemoveAt(0);
if (curr == n - 1) {
return count / 2;
}
if (curr + 1 < n
&& visited[curr + 1] == false ) {
q.Add(curr + 1);
visited[curr + 1] = true ;
}
if (curr - 1 >= 0
&& visited[curr - 1] == false ) {
q.Add(curr - 1);
visited[curr - 1] = true ;
}
if (unmap.ContainsKey(arr[i])){
for ( int j = 0; j < unmap[arr[curr]].Count; j++) {
int child= unmap[arr[curr]][j];
if (curr == child) {
continue ;
}
if (visited[child] == false ) {
q.Add(child);
visited[child] = true ;
}
}
}
unmap.Remove(arr[curr]);
}
count++;
}
return count / 2;
}
static public void Main ( string [] args){
int [] arr = { 100, -23, -23, 404, 100,
23, 23, 23, 3, 404 };
Console.WriteLine(minimizeJumps(arr));
}
}
|
Javascript
function minimizeJumps(arr)
{
let n = arr.length;
let unmap = new Map();
for (let i = 0; i < n; i++) {
if (unmap.has(arr[i]))
unmap.get(arr[i]).push(i);
else
unmap.set(arr[i], [i]);
}
let q = [];
let visited = new Array(n).fill(0);
q.push(0);
visited[0] = true ;
let count = 0;
while (q.length > 0) {
let size = q.length;
for (let i = 0; i < size; i++) {
let curr = q.shift();
if (curr == n - 1) {
return count / 2;
}
if (curr + 1 < n
&& visited[curr + 1] == false ) {
q.push(curr + 1);
visited[curr + 1] = true ;
}
if (curr - 1 >= 0
&& visited[curr - 1] == false ) {
q.push(curr - 1);
visited[curr - 1] = true ;
}
if (unmap.has(arr[i])) {
for (let i = 0;
i < unmap.get(arr[curr]).length; i++) {
child = unmap.get(arr[curr])[i];
if (curr == child)
continue ;
if (visited[child] == false ) {
q.push(child);
visited[child] = true ;
}
}
}
unmap. delete (arr[curr]);
}
count++;
}
return count / 2;
}
let arr = [ 100, -23, -23, 404, 100, 23, 23, 23, 3, 404 ];
console.log(minimizeJumps(arr));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...