给定由N个正整数组成的两个数组arr []和jumps [] ,每个数组元素arr [i]的任务是找到达到相对奇偶性元素所需的最小跳转数。从任何数组元素arr [i]唯一可能的跳转是(i + jumps [i])或(i – jumps [i]) 。
例子:
Input: arr[] = {4, 2, 5, 2, 1}, jumps[] = {1, 2, 3, 1, 2}
Output: 3 2 -1 1 -1
Explanation:
Below are the minimum steps required for each element:
arr[4]: Since jumps[4] = 2, the only possible jump is (4 – jumps[4]) = 2. Snce arr[2] is of same parity as arr[4] and no further jump within the range of array indice is possible, print -1.
arr[3]: Since jumps[3] = 1, both the jumps (3 + jumps[3]) = 4 or (3 – jumps[3]) = 2 are possible. Since both the elements arr[2] and arr[4] are of opposite parity with arr[3], print 1.
arr[2]: Print -1.
arr[1]: Only possible jump is (2 + jumps[2]). Since arr[3] is of same parity as arr[2] and minimum jumps required from arr[3] to reach an array element of opposite parity is 1, the number of jumps required is 2.
arr[0]: arr[0] -> arr[3] -> (arr[4] or arr[2]). Therefore, minimum jumps required is 3.
Input: arr[] = {4, 5, 7, 6, 7, 5, 4, 4, 6, 4}, jumps[] = {1, 2, 3, 3, 5, 2, 7, 2, 4, 1}
Output: 1 1 2 2 1 1 -1 1 1 2
天真的方法:最简单的方法是解决问题,方法是遍历数组并通过重复转换为arr [i – jumps [i]]和arr [i + jumps ]对每个数组元素arr [i]执行广度优先遍历[i] ,直到出现无效索引,并且在每次转换之后,检查数组元素是否与前一个元素具有相反的奇偶校验。相应地打印每个数组元素所需的最小跳转数。
时间复杂度: O(N 2 )
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是将多源BFS分别用于偶数和奇数数组元素。请按照以下步骤解决问题:
- 初始化一个向量,例如ans [] ,以存储每个数组元素到达具有相反奇偶性的元素所需的最小跳转。
- 初始化向量数组Adj []以存储生成的图的邻接表。
- 对于每个索引的每对有效跳数(i,j) ,数组的i通过将边初始化为(j,i)来创建一个倒置图。
- 对奇数元素执行多源BFS遍历。执行以下步骤:
- 将包含奇数数组元素的所有索引推入队列,并将所有这些节点标记为同时访问。
- 迭代直到队列为非空,然后执行以下操作:
- 弹出出现在队列最前面的节点,并检查现在连接到该节点的任何节点是否具有相同的奇偶校验。如果发现为真,则将子节点的距离更新为1 +父节点的距离。
- 将子节点标记为已访问并将其推入队列。
- 对偶数元素执行多源BFS遍历,并将距离存储在ans []中。
- 完成上述步骤后,打印存储在ans []中的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Bfs for odd numbers are source
void bfs(int n, vector& a,
vector invGr[],
vector& ans, int parity)
{
// Initialize queue
queue q;
// Stores for each node, the nodes
// visited and their distances
vector vis(n + 1, 0);
vector dist(n + 1, 0);
// Push odd and even numbers
// as sources to the queue
// If parity is 0 -> odd
// Otherwise -> even
for (int i = 1; i <= n; i++) {
if ((a[i] + parity) & 1) {
q.push(i);
vis[i] = 1;
}
}
// Peform multi-source bfs
while (!q.empty()) {
// Extract the front element
// of the queue
int v = q.front();
q.pop();
// Traverse nodes connected
// to the current node
for (int u : invGr[v]) {
// If u is not visited
if (!vis[u]) {
dist[u] = dist[v] + 1;
vis[u] = 1;
// If element with opposite
// parity is obtained
if ((a[u] + parity) % 2 == 0) {
if (ans[u] == -1)
// Store its distance from
// source in ans[]
ans[u] = dist[u];
}
// Push the current neighbour
// to the queue
q.push(u);
}
}
}
}
// Function to find the minimum jumps
// required by each index to reach
// element of opposite parity
void minJumps(vector& a,
vector& jump, int n)
{
// Initialise Inverse Graph
vector invGr[n + 1];
// Stores the result for each index
vector ans(n + 1, -1);
for (int i = 1; i <= n; i++) {
// For the jumped index
for (int ind : { i + jump[i],
i - jump[i] }) {
// If the ind is valid then
// add reverse directed edge
if (ind >= 1 and ind <= n) {
invGr[ind].push_back(i);
}
}
}
// Multi-source bfs with odd
// numbers as source by passing 0
bfs(n, a, invGr, ans, 0);
// Multi-source bfs with even
// numbers as source by passing 1
bfs(n, a, invGr, ans, 1);
// Print the answer
for (int i = 1; i <= n; i++) {
cout << ans[i] << ' ';
}
}
// Driver Code
int main()
{
vector arr = { 0, 4, 2, 5, 2, 1 };
vector jump = { 0, 1, 2, 3, 1, 2 };
int N = arr.size();
minJumps(arr, jump, N - 1);
return 0;
}
Java
// Java program for above approach
import java.util.*;
import java.lang.*;
class Gfg
{
// Bfs for odd numbers are source
static void bfs(int n, int[] a,
ArrayList> invGr,
int[] ans, int parity)
{
// Initialize queue
Queue q = new LinkedList<>();
// Stores for each node, the nodes
// visited and their distances
int[] vis = new int[n + 1];
int[] dist = new int[n + 1];
// Push odd and even numbers
// as sources to the queue
// If parity is 0 -> odd
// Otherwise -> even
for (int i = 1; i <= n; i++) {
if (((a[i] + parity) & 1) != 0) {
q.add(i);
vis[i] = 1;
}
}
// Peform multi-source bfs
while (!q.isEmpty()) {
// Extract the front element
// of the queue
int v = q.peek();
q.poll();
// Traverse nodes connected
// to the current node
for (Integer u : invGr.get(v)) {
// If u is not visited
if (vis[u] == 0) {
dist[u] = dist[v] + 1;
vis[u] = 1;
// If element with opposite
// parity is obtained
if ((a[u] + parity) % 2 == 0) {
if (ans[u] == -1)
// Store its distance from
// source in ans[]
ans[u] = dist[u];
}
// Push the current neighbour
// to the queue
q.add(u);
}
}
}
}
// Function to find the minimum jumps
// required by each index to reach
// element of opposite parity
static void minJumps(int[] a,
int[] jump, int n)
{
// Initialise Inverse Graph
ArrayList> invGr = new ArrayList<>();
for(int i = 0; i <= n; i++)
invGr.add(new ArrayList());
// Stores the result for each index
int[] ans = new int[n + 1];
Arrays.fill(ans, -1);
for (int i = 1; i <= n; i++)
{
// For the jumped index
// If the ind is valid then
// add reverse directed edge
if (i+ jump[i] >= 1 && i+jump[i] <= n) {
invGr.get(i+ jump[i]).add(i);
}
if (i-jump[i] >= 1 && i-jump[i] <= n) {
invGr.get(i- jump[i]).add(i);
}
}
// Multi-source bfs with odd
// numbers as source by passing 0
bfs(n, a, invGr, ans, 0);
// Multi-source bfs with even
// numbers as source by passing 1
bfs(n, a, invGr, ans, 1);
// Print the answer
for (int i = 1; i <= n; i++)
{
System.out.print(ans[i] + " ");
}
}
// Driver function
public static void main (String[] args)
{
int[] arr = { 0, 4, 2, 5, 2, 1 };
int[] jump = { 0, 1, 2, 3, 1, 2 };
int N = arr.length;
minJumps(arr, jump, N - 1);
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Bfs for odd numbers are source
def bfs(n, a, invGr, ans, parity):
# Initialize queue
q = []
# Stores for each node, the nodes
# visited and their distances
vis = [0 for i in range(n + 1)]
dist = [0 for i in range(n + 1)]
# Push odd and even numbers
# as sources to the queue
# If parity is 0 -> odd
# Otherwise -> even
for i in range(1, n + 1):
if ((a[i] + parity) & 1):
q.append(i)
vis[i] = 1
# Peform multi-source bfs
while (len(q) != 0):
# Extract the front element
# of the queue
v = q[0]
q.pop(0)
# Traverse nodes connected
# to the current node
for u in invGr[v]:
# If u is not visited
if (not vis[u]):
dist[u] = dist[v] + 1
vis[u] = 1
# If element with opposite
# parity is obtained
if ((a[u] + parity) % 2 == 0):
if (ans[u] == -1):
# Store its distance from
# source in ans[]
ans[u] = dist[u]
# Push the current neighbour
# to the queue
q.append(u)
# Function to find the minimum jumps
# required by each index to reach
# element of opposite parity
def minJumps(a, jump, n):
# Initialise Inverse Graph
invGr = [[] for i in range(n + 1)]
# Stores the result for each index
ans = [-1 for i in range(n + 1)]
for i in range(1, n + 1):
# For the jumped index
for ind in [i + jump[i], i - jump[i]]:
# If the ind is valid then
# add reverse directed edge
if (ind >= 1 and ind <= n):
invGr[ind].append(i)
# Multi-source bfs with odd
# numbers as source by passing 0
bfs(n, a, invGr, ans, 0)
# Multi-source bfs with even
# numbers as source by passing 1
bfs(n, a, invGr, ans, 1)
# Print the answer
for i in range(1, n + 1):
print(str(ans[i]), end = ' ')
# Driver Code
if __name__=='__main__':
arr = [ 0, 4, 2, 5, 2, 1 ]
jump = [ 0, 1, 2, 3, 1, 2 ]
N = len(arr)
minJumps(arr, jump, N - 1)
# This code is contributed by pratham76
3 2 -1 1 -1
时间复杂度: O(N)
辅助空间: O(N)