根据给定条件达到数组中给定索引的最小步骤
给定一个大小为N的数组arr[ ] ,仅包含整数-1 、 0 、 1和一个由查询组成的数组q[ ] 。在数组arr[ ] 中,-1表示它左边的任何索引都可以到达, 1表示它右边的任何索引都可以从该索引到达。特定查询中的索引不能直接访问,但所有其他索引都可以访问。为每个查询找到从其相邻索引(以最近者为准)到达任何索引所需的最小步骤数,并最终返回结果数组。如果任何索引不可达,则返回-1 。
例子:
Input: arr[ ] = {0, 0, -1, 0, 1, 0, 0, 1, 1, -1, 0}, q[ ] = {3, 6}
Output: result[ ] = {6, 2}
Explanation: There is only 1 way to reach index 3, i.e. from index 9. Therefore minimum distance= 9-3=6
The shortest path to reach index 6 is via index 4. Therefore minimum distance=6-4=2
result[ ]={6, 2}
Input: arr[ ] = {-1, 0, 0, 0, 1}, q[ ] = {2, 0}
Output: result[ ] = {-1, 0}
方法:这个想法是存储距离左侧最近的1和距离右侧最近的-1的索引,然后在为每个查询q[i]遍历数组q[ ] 时,检查两边的距离并存储最小的一个。请按照以下步骤解决问题:
- 初始化向量result[]、v1[]和v2[]以存储每个查询的结果,以及最接近的1和-1。
- 将变量last_1和last_m1初始化为-1以存储最新的1和-1。
- 使用变量i遍历范围[0, N]并执行以下任务:
- 将last_1的值推入向量v2[]。
- 如果arr[i]等于1,则将last_1的值设置为i。
- 使用变量i遍历范围[N-1, 0]并执行以下任务:
- 将last_m1的值推入向量v2[]。
- 如果arr[i]等于-1,则将last_m1的值设置为i。
- 反转向量v1[]。
- 使用变量i遍历范围[0, M]并执行以下任务:
- 如果v1[q[i]]和v2[q[i]]不等于-1,则将值result[i]设置为abs(v1[q[i]] – q[i])的最小值或abs(v2[q[i]] – q[i])。
- 否则,如果v1[q[i]]不等于-1,则将值result[i]设置为abs(v1[q[i]] – q[i])。
- 否则,如果v2[q[i]]不等于-1,则将值result[i]设置为abs(v2[q[i]] – q[i])。
- 否则,将result[i]的值设置为-1。
- 执行上述步骤后,打印向量result[]作为答案。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Function to return the min distance
// from neighboring index
vector res(int arr[], int q[], int n, int m)
{
// Vectors result, v1 and v2 to
// store the minimum distance, index
// of -1 and 1 respectively
vector result, v1, v2;
// Variables to store the last
// position of -1 and 1
int last_m1 = -1, last_1 = -1;
// Traverse over the array arr[]
// to store the index of 1
for (int i = 0; i < n; i++) {
v2.push_back(last_1);
if (arr[i] == 1)
last_1 = i;
}
// Traverse over the array arr[]
// to store the index of -1
for (int i = n - 1; i >= 0; i--) {
v1.push_back(last_m1);
if (arr[i] == -1)
last_m1 = i;
}
// Reverse v1 to get the original order
reverse(v1.begin(), v1.end());
// Traverse over the array q[]
for (int i = 0; i < m; i++) {
if (v1[q[i]] != -1 and v2[q[i]] != -1)
result.push_back(
min(abs(v1[q[i]] - q[i]),
abs(v2[q[i]] - q[i])));
else if (v1[q[i]] != -1)
result.push_back(
abs(v1[q[i]] - q[i]));
else if (v2[q[i]] != -1)
result.push_back(
abs(v2[q[i]] - q[i]));
else
result.push_back(-1);
}
// Finally return the vector of result
return result;
}
// Driver Code
int main()
{
// Input
int arr[] = { -1, 0, 0, 1, -1, 1,
1, 0, 0, 1, -1, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
// Query
int q[] = { 1, 5, 10 };
int m = sizeof(q) / sizeof(q[0]);
// Function call to find the minimum distance
vector x = res(arr, q, n, m);
// Print the resultant vector
for (auto y : x)
cout << y << " ";
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to return the min distance
// from neighboring index
static Vector res(int arr[], int q[], int n, int m)
{
// Vectors result, v1 and v2 to
// store the minimum distance, index
// of -1 and 1 respectively
Vector result = new Vector(),
v1= new Vector(),
v2= new Vector();
// Variables to store the last
// position of -1 and 1
int last_m1 = -1, last_1 = -1;
// Traverse over the array arr[]
// to store the index of 1
for (int i = 0; i < n; i++) {
v2.add(last_1);
if (arr[i] == 1)
last_1 = i;
}
// Traverse over the array arr[]
// to store the index of -1
for (int i = n - 1; i >= 0; i--) {
v1.add(last_m1);
if (arr[i] == -1)
last_m1 = i;
}
// Reverse v1 to get the original order
Collections.reverse(v1);
// Traverse over the array q[]
for (int i = 0; i < m; i++) {
if (v1.get(q[i]) != -1 && v2.get(q[i]) != -1)
result.add(
Math.min(Math.abs(v1.get(q[i]) - q[i]),
Math.abs(v2.get(q[i]) - q[i])));
else if (v1.get(q[i]) != -1)
result.add(
Math.abs(v1.get(q[i]) - q[i]));
else if (v2.get(q[i]) != -1)
result.add(
Math.abs(v2.get(q[i]) - q[i]));
else
result.add(-1);
}
// Finally return the vector of result
return result;
}
// Driver Code
public static void main(String[] args)
{
// Input
int arr[] = { -1, 0, 0, 1, -1, 1,
1, 0, 0, 1, -1, 0 };
int n = arr.length;
// Query
int q[] = { 1, 5, 10 };
int m = q.length;
// Function call to find the minimum distance
Vector x = res(arr, q, n, m);
// Print the resultant vector
for (int y : x)
System.out.print(y+ " ");
}
}
// This code is contributed by shikhasingrajput
Python3
# python program for the above approach
# Function to return the min distance
# from neighboring index
def res(arr, q, n, m):
# Vectors result, v1 and v2 to
# store the minimum distance, index
# of -1 and 1 respectively
result = []
v1 = []
v2 = []
# Variables to store the last
# position of -1 and 1
last_m1 = -1
last_1 = -1
# Traverse over the array arr[]
# to store the index of 1
for i in range(0, n):
v2.append(last_1)
if (arr[i] == 1):
last_1 = i
# Traverse over the array arr[]
# to store the index of -1
for i in range(n-1, -1, -1):
v1.append(last_m1)
if (arr[i] == -1):
last_m1 = i
# Reverse v1 to get the original order
v1.reverse()
# Traverse over the array q[]
for i in range(0, m):
if (v1[q[i]] != -1 and v2[q[i]] != -1):
result.append(min(abs(v1[q[i]] - q[i]), abs(v2[q[i]] - q[i])))
elif (v1[q[i]] != -1):
result.append(abs(v1[q[i]] - q[i]))
elif (v2[q[i]] != -1):
result.append(abs(v2[q[i]] - q[i]))
else:
result.push_back(-1)
# Finally return the vector of result
return result
# Driver Code
if __name__ == "__main__":
# Input
arr = [-1, 0, 0, 1, -1, 1, 1, 0, 0, 1, -1, 0]
n = len(arr)
# Query
q = [1, 5, 10]
m = len(q)
# Function call to find the minimum distance
x = res(arr, q, n, m)
# Print the resultant vector
for y in x:
print(y, end=" ")
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return the min distance
// from neighboring index
static List res(int[] arr, int[] q, int n, int m)
{
// Vectors result, v1 and v2 to
// store the minimum distance, index
// of -1 and 1 respectively
List result = new List();
List v1 = new List();
List v2 = new List();
// Variables to store the last
// position of -1 and 1
int last_m1 = -1, last_1 = -1;
// Traverse over the array arr[]
// to store the index of 1
for (int i = 0; i < n; i++) {
v2.Add(last_1);
if (arr[i] == 1)
last_1 = i;
}
// Traverse over the array arr[]
// to store the index of -1
for (int i = n - 1; i >= 0; i--) {
v1.Add(last_m1);
if (arr[i] == -1)
last_m1 = i;
}
// Reverse v1 to get the original order
v1.Reverse();
// Traverse over the array q[]
for (int i = 0; i < m; i++) {
if (v1[q[i]] != -1 && v2[q[i]] != -1)
result.Add(
Math.Min(Math.Abs(v1[q[i]] - q[i]),
Math.Abs(v2[q[i]] - q[i])));
else if (v1[q[i]] != -1)
result.Add(Math.Abs(v1[q[i]] - q[i]));
else if (v2[q[i]] != -1)
result.Add(Math.Abs(v2[q[i]] - q[i]));
else
result.Add(-1);
}
// Finally return the vector of result
return result;
}
// Driver Code
public static void Main()
{
// Input
int[] arr
= { -1, 0, 0, 1, -1, 1, 1, 0, 0, 1, -1, 0 };
int n = arr.Length;
// Query
int[] q = { 1, 5, 10 };
int m = q.Length;
// Function call to find the minimum distance
List x = res(arr, q, n, m);
// Print the resultant vector
foreach(int y in x) Console.Write(y + " ");
}
}
// This code is contributed by ukasp.
Javascript
3 2 1
时间复杂度: O(N+M) 其中 N 是arr[ ]的大小,M 是q[ ]的大小
辅助空间: O(N)