给定由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]进行广度优先遍历,通过反复转换为arr[i – jumps[i]]和arr[i + jumps [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;
}
}
// Perform 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;
}
}
// Perform 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
# Perform 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
Javascript
3 2 -1 1 -1
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。