📌  相关文章
📜  在约束下到达数组末尾的最小步骤

📅  最后修改于: 2022-05-13 01:57:51.362000             🧑  作者: Mango

在约束下到达数组末尾的最小步骤

给定一个仅包含一位数字的数组,假设我们站在第一个索引处,我们需要使用最少的步数到达数组的末尾,在一个步骤中,我们可以跳转到相邻索引或可以跳转到具有相同值的位置.
换句话说,如果我们在索引 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