在约束下到达数组末尾的最小步骤
给定一个仅包含一位数字的数组,假设我们站在第一个索引处,我们需要使用最少的步数到达数组的末尾,在一个步骤中,我们可以跳转到相邻索引或可以跳转到具有相同值的位置.
换句话说,如果我们在索引 i 处,那么在一个步骤中,您可以到达 arr[i-1] 或 arr[i+1] 或 arr[K] 使得 arr[K] = arr[i] ( arr[K] 的值与 arr[i] 相同)
例子:
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)
这个问题可以使用 BFS 来解决。我们可以将给定的数组视为未加权图,其中每个顶点都有两条边到下一个和前一个数组元素,而更多边到具有相同值的数组元素。现在为了快速处理第三种类型的边,我们保留了 10 个向量,这些向量存储存在数字 0 到 9 的所有索引。在上面的示例中,对应于 0 的向量将存储 [0, 12],2 个索引,其中 0 在给定数组中出现。
使用了另一个布尔数组,这样我们就不会多次访问同一个索引。由于我们逐级使用 BFS 和 BFS 收益,因此可以保证最优的最小步数。
C++
// C++ program to find minimum jumps to reach end
// of array
#include
using namespace std;
// Method returns minimum step to reach end of array
int getMinStepToReachEnd(int arr[], int N)
{
// visit boolean array checks whether current index
// is previously visited
bool visit[N];
// distance array stores distance of current
// index from starting index
int distance[N];
// digit vector stores indices where a
// particular number resides
vector digit[10];
// In starting all index are unvisited
memset(visit, false, sizeof(visit));
// storing indices of each number in digit vector
for (int i = 1; i < N; i++)
digit[arr[i]].push_back(i);
// for starting index distance will be zero
distance[0] = 0;
visit[0] = true;
// Creating a queue and inserting index 0.
queue q;
q.push(0);
// loop until queue in not empty
while(!q.empty())
{
// Get an item from queue, q.
int idx = q.front(); q.pop();
// If we reached to last index break from loop
if (idx == N-1)
break;
// Find value of dequeued index
int d = arr[idx];
// looping for all indices with value as d.
for (int i = 0; i= 0 && !visit[idx - 1])
{
visit[idx - 1] = true;
q.push(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
// checking condition for next index
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true;
q.push(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
// N-1th position has the final result
return distance[N - 1];
}
// driver code to test above methods
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
// Java program to find minimum jumps
// to reach end of array
import java.util.*;
class GFG
{
// Method returns minimum step
// to reach end of array
static int getMinStepToReachEnd(int arr[],
int N)
{
// visit boolean array checks whether
// current index is previously visited
boolean []visit = new boolean[N];
// distance array stores distance of
// current index from starting index
int []distance = new int[N];
// digit vector stores indices where a
// particular number resides
Vector []digit = new Vector[10];
for(int i = 0; i < 10; i++)
digit[i] = new Vector<>();
// In starting all index are unvisited
for(int i = 0; i < N; i++)
visit[i] = false;
// storing indices of each number
// in digit vector
for (int i = 1; i < N; i++)
digit[arr[i]].add(i);
// for starting index distance will be zero
distance[0] = 0;
visit[0] = true;
// Creating a queue and inserting index 0.
Queue q = new LinkedList<>();
q.add(0);
// loop until queue in not empty
while(!q.isEmpty())
{
// Get an item from queue, q.
int idx = q.peek();
q.remove();
// If we reached to last
// index break from loop
if (idx == N - 1)
break;
// Find value of dequeued index
int d = arr[idx];
// looping for all indices with value as d.
for (int i = 0; i < digit[d].size(); i++)
{
int nextidx = digit[d].get(i);
if (!visit[nextidx])
{
visit[nextidx] = true;
q.add(nextidx);
// update the distance of this nextidx
distance[nextidx] = distance[idx] + 1;
}
}
// clear all indices for digit d,
// because all of them are processed
digit[d].clear();
// checking condition for previous index
if (idx - 1 >= 0 && !visit[idx - 1])
{
visit[idx - 1] = true;
q.add(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
// checking condition for next index
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true;
q.add(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
// N-1th position has the final result
return distance[N - 1];
}
// Driver Code
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));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python 3 program to find minimum jumps to reach end# of array
# Method returns minimum step to reach end of array
def getMinStepToReachEnd(arr,N):
# visit boolean array checks whether current index
# is previously visited
visit = [False for i in range(N)]
# distance array stores distance of current
# index from starting index
distance = [0 for i in range(N)]
# digit vector stores indices where a
# particular number resides
digit = [[0 for i in range(N)] for j in range(10)]
# storing indices of each number in digit vector
for i in range(1,N):
digit[arr[i]].append(i)
# for starting index distance will be zero
distance[0] = 0
visit[0] = True
# Creating a queue and inserting index 0.
q = []
q.append(0)
# loop until queue in not empty
while(len(q)> 0):
# Get an item from queue, q.
idx = q[0]
q.remove(q[0])
# If we reached to last index break from loop
if (idx == N-1):
break
# Find value of dequeued index
d = arr[idx]
# looping for all indices with value as d.
for i in range(len(digit[d])):
nextidx = digit[d][i]
if (visit[nextidx] == False):
visit[nextidx] = True
q.append(nextidx)
# update the distance of this nextidx
distance[nextidx] = distance[idx] + 1
# clear all indices for digit d, because all
# of them are processed
# checking condition for previous index
if (idx-1 >= 0 and visit[idx - 1] == False):
visit[idx - 1] = True
q.append(idx - 1)
distance[idx - 1] = distance[idx] + 1
# checking condition for next index
if (idx + 1 < N and visit[idx + 1] == False):
visit[idx + 1] = True
q.append(idx + 1)
distance[idx + 1] = distance[idx] + 1
# N-1th position has the final result
return distance[N - 1]
# driver code to test above methods
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))
# This code is contributed by
# Surendra_Gangwar
C#
// C# program to find minimum jumps
// to reach end of array
using System;
using System.Collections.Generic;
class GFG
{
// Method returns minimum step
// to reach end of array
static int getMinStepToReachEnd(int []arr,
int N)
{
// visit boolean array checks whether
// current index is previously visited
bool []visit = new bool[N];
// distance array stores distance of
// current index from starting index
int []distance = new int[N];
// digit vector stores indices where a
// particular number resides
List []digit = new List[10];
for(int i = 0; i < 10; i++)
digit[i] = new List();
// In starting all index are unvisited
for(int i = 0; i < N; i++)
visit[i] = false;
// storing indices of each number
// in digit vector
for (int i = 1; i < N; i++)
digit[arr[i]].Add(i);
// for starting index distance will be zero
distance[0] = 0;
visit[0] = true;
// Creating a queue and inserting index 0.
Queue q = new Queue();
q.Enqueue(0);
// loop until queue in not empty
while(q.Count != 0)
{
// Get an item from queue, q.
int idx = q.Peek();
q.Dequeue();
// If we reached to last
// index break from loop
if (idx == N - 1)
break;
// Find value of dequeued index
int d = arr[idx];
// looping for all indices with value as d.
for (int i = 0; i < digit[d].Count; i++)
{
int nextidx = digit[d][i];
if (!visit[nextidx])
{
visit[nextidx] = true;
q.Enqueue(nextidx);
// update the distance of this nextidx
distance[nextidx] = distance[idx] + 1;
}
}
// clear all indices for digit d,
// because all of them are processed
digit[d].Clear();
// checking condition for previous index
if (idx - 1 >= 0 && !visit[idx - 1])
{
visit[idx - 1] = true;
q.Enqueue(idx - 1);
distance[idx - 1] = distance[idx] + 1;
}
// checking condition for next index
if (idx + 1 < N && !visit[idx + 1])
{
visit[idx + 1] = true;
q.Enqueue(idx + 1);
distance[idx + 1] = distance[idx] + 1;
}
}
// N-1th position has the final result
return distance[N - 1];
}
// Driver Code
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));
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
5