通过从 arr[i] 跳转到 arr[arr[i]] 到达 Array 末尾的跳转次数
给定一个包含N个整数的数组arr[] ,任务是找出所有i值作为起始索引的数组arr[]转义所需的跳转次数,该索引位于[0, N)范围内,其中唯一可能的跳转来自arr[i]是到arr[arr[i]]并且转义数组意味着arr[i]>=N ,即下一个跳转的索引不存在。
例子:
Input: arr[] = {2, 3, 4, 1, 10}
Output: 3 -1 2 -1 1
Explanation:
- For i = 0, initially the current index x is 0. After the 1st jump, the current index becomes x = arr[x] = arr[0] = 2. Similarly, after the 2nd jump, the current index becomes x = arr[2] = 4. After the 3rd jump x = arr[4] =10, which is greater than the array size. Therefore the number of steps required to escape the array is 3.
- For i = 1, initially the current index x is 1. After the 1st jump, x = arr[1] = 3. After the 2nd jump, x = arr[3] = 1, which has already been visited and hence forming a closed loop. Therefore it is impossible to escape the array from index 1.
Input: arr[] = {3, 12, 2, 7, 4, 10, 35, 5, 9, 27}
Output: 4 1 -1 3 -1 1 1 2 2 1
方法:给定的问题可以在递归的帮助下解决。以下是要遵循的步骤:
- 创建一个数组visited[] ,它存储当前索引是否已经被访问过。最初, visited = {0} 。
- 创建一个数组cntJumps[] ,它存储 [0, N) 范围内所有索引所需的跳转次数。最初, cntJumps = {0} 。
- 创建一个递归函数countJumps() ,它计算从当前索引中转义数组所需的跳转次数。
- 在函数countJumps()中,如果已经计算出当前索引的答案,则返回 answer else 如果当前节点已经被访问,则返回-1否则如果从当前索引跳转后数组将被转义,则返回1 。
- 递归计算当前跳转后的跳转次数,即countJumps(i) = 1 + countJumps(arr[i]) 。将答案存储在数组cntJumps[]中。
- 打印数组cntJumps[] ,这是必需的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Stores the number of jumps
int cntJumps[100];
// Stores if the current index is visited
int visited[100];
// Recursive function to find the number of
// jumps to escape the array from index i
int countJumps(int arr[], int N, int i)
{
// If the answer for the current index is
// already calculated
if (cntJumps[i] != 0) {
return cntJumps[i];
}
// If the current index is already visited
if (visited[i]) {
return -1;
}
// Mark current index as visited
visited[i] = true;
// If the array is escaped after the jump
// from the current index
if (arr[i] >= N) {
return cntJumps[i] = 1;
}
// Recursive call for the next jump
int val = countJumps(arr, N, arr[i]);
// If it is impossible to escape the array
if (val == -1)
cntJumps[i] = -1;
else
cntJumps[i] = 1 + val;
// Return answer
return cntJumps[i];
}
// Function to print the number of jumps
// required to escape the array from
// ith index for all values of i in [0, N)
void printCountJumps(int arr[], int N)
{
// Initialize visited array as 0
memset(visited, 0, sizeof(visited));
// Initialize cntJump array by 0
memset(cntJumps, 0, sizeof(cntJumps));
// Loop to iterate over all values of i
for (int i = 0; i < N; i++) {
// If the index i is not visited already
if (!visited[i]) {
countJumps(arr, N, i);
}
}
// Print Answer
for (int i = 0; i < N; i++) {
cout << cntJumps[i] << " ";
}
}
// Driver Code
int main()
{
int arr[] = { 3, 12, 2, 7, 4, 10, 35, 5, 9, 27 };
int N = sizeof(arr) / sizeof(arr[0]);
printCountJumps(arr, N);
return 0;
}
Java
// Java program for the above approach
public class GFG {
// Stores the number of jumps
static int cntJumps[] = new int[100];
// Stores if the current index is visited
static int visited[] = new int[100];
// Recursive function to find the number of
// jumps to escape the array from index i
static int countJumps(int arr[], int N, int i)
{
// If the answer for the current index is
// already calculated
if (cntJumps[i] != 0) {
return cntJumps[i];
}
// If the current index is already visited
if (visited[i] != 0) {
return -1;
}
// Mark current index as visited
visited[i] = 1;
// If the array is escaped after the jump
// from the current index
if (arr[i] >= N) {
cntJumps[i] = 1;
return cntJumps[i];
}
// Recursive call for the next jump
int val = countJumps(arr, N, arr[i]);
// If it is impossible to escape the array
if (val == -1)
cntJumps[i] = -1;
else
cntJumps[i] = 1 + val;
// Return answer
return cntJumps[i];
}
// Function to print the number of jumps
// required to escape the array from
// ith index for all values of i in [0, N)
static void printCountJumps(int arr[], int N)
{
// Initialize visited array as 0
for (int i = 0; i < visited.length; i++)
visited[i] = 0;
// Initialize cntJump array by 0
for (int i = 0; i < cntJumps.length; i++)
cntJumps[i] = 0;
// Loop to iterate over all values of i
for (int i = 0; i < N; i++) {
// If the index i is not visited already
if (visited[i] == 0) {
countJumps(arr, N, i);
}
}
// Print Answer
for (int i = 0; i < N; i++) {
System.out.print(cntJumps[i] + " ");
}
}
// Driver Code
public static void main (String[] args)
{
int arr[] = { 3, 12, 2, 7, 4, 10, 35, 5, 9, 27 };
int N = arr.length;
printCountJumps(arr, N);
}
}
// This code is contributed by AnkThon
Python3
# Python program for the above approach
# Stores the number of jumps
cntJumps = [0 for _ in range(100)]
# Stores if the current index is visited
visited = [0 for _ in range(100)]
# Recursive function to find the number of
# jumps to escape the array from index i
def countJumps(arr, N, i):
global visited
global cntJumps
# If the answer for the current index is
# already calculated
if (cntJumps[i] != 0):
return cntJumps[i]
# If the current index is already visited
if (visited[i]):
return -1
# Mark current index as visited
visited[i] = True
# If the array is escaped after the jump
# from the current index
if (arr[i] >= N):
cntJumps[i] = 1
return cntJumps[i]
# Recursive call for the next jump
val = countJumps(arr, N, arr[i])
# If it is impossible to escape the array
if (val == -1):
cntJumps[i] = -1
else:
cntJumps[i] = 1 + val
# Return answer
return cntJumps[i]
# Function to print the number of jumps
# required to escape the array from
# ith index for all values of i in [0, N)
def printCountJumps(arr, N):
# Loop to iterate over all values of i
for i in range(0, N):
# If the index i is not visited already
if (not visited[i]):
countJumps(arr, N, i)
# Print Answer
for i in range(0, N):
print(cntJumps[i], end=" ")
# Driver Code
if __name__ == "__main__":
arr = [3, 12, 2, 7, 4, 10, 35, 5, 9, 27]
N = len(arr)
printCountJumps(arr, N)
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
public class GFG {
// Stores the number of jumps
static int []cntJumps = new int[100];
// Stores if the current index is visited
static int []visited = new int[100];
// Recursive function to find the number of
// jumps to escape the array from index i
static int countJumps(int []arr, int N, int i)
{
// If the answer for the current index is
// already calculated
if (cntJumps[i] != 0) {
return cntJumps[i];
}
// If the current index is already visited
if (visited[i] != 0) {
return -1;
}
// Mark current index as visited
visited[i] = 1;
// If the array is escaped after the jump
// from the current index
if (arr[i] >= N) {
cntJumps[i] = 1;
return cntJumps[i];
}
// Recursive call for the next jump
int val = countJumps(arr, N, arr[i]);
// If it is impossible to escape the array
if (val == -1)
cntJumps[i] = -1;
else
cntJumps[i] = 1 + val;
// Return answer
return cntJumps[i];
}
// Function to print the number of jumps
// required to escape the array from
// ith index for all values of i in [0, N)
static void printCountJumps(int []arr, int N)
{
// Initialize visited array as 0
for (int i = 0; i < visited.Length; i++)
visited[i] = 0;
// Initialize cntJump array by 0
for (int i = 0; i < cntJumps.Length; i++)
cntJumps[i] = 0;
// Loop to iterate over all values of i
for (int i = 0; i < N; i++) {
// If the index i is not visited already
if (visited[i] == 0) {
countJumps(arr, N, i);
}
}
// Print Answer
for (int i = 0; i < N; i++) {
Console.Write(cntJumps[i] + " ");
}
}
// Driver Code
public static void Main (string[] args)
{
int []arr = { 3, 12, 2, 7, 4, 10, 35, 5, 9, 27 };
int N = arr.Length;
printCountJumps(arr, N);
}
}
// This code is contributed by AnkThon
Javascript
输出:
4 1 -1 3 -1 1 1 2 2 1
时间复杂度: O(N)
辅助空间: O(N)