This approach involves using Breadth-First Search (BFS) to precompute the minimum Manhattan distance from each cell to any thief in the grid, and then using this information to find the maximum safeness factor for reaching the bottom-right corner.
Time Complexity: O(n2 log n), where n is the grid size, due to the Dijkstra-like process.
Space Complexity: O(n2) for storing distances and safeness factors.
1#include <iostream>
2#include <vector>
3#include <queue>
4#include <climits>
5
6using namespace std;
7
8const int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
9
10int maxSafenessFactor(vector<vector<int>>& grid) {
11 int n = grid.size();
12 vector<vector<int>> distance(n, vector<int>(n, INT_MAX));
13 queue<pair<int, int>> q;
14
15 // BFS to calculate initial distances to the nearest thief
16 for (int r = 0; r < n; ++r) {
17 for (int c = 0; c < n; ++c) {
18 if (grid[r][c] == 1) {
19 q.push({r, c});
20 distance[r][c] = 0;
21 }
22 }
23 }
24
25 while (!q.empty()) {
26 auto [r, c] = q.front(); q.pop();
27 for (auto& dir : directions) {
28 int nr = r + dir[0], nc = c + dir[1];
29 if (nr >= 0 && nr < n && nc >= 0 && nc < n && distance[nr][nc] == INT_MAX) {
30 distance[nr][nc] = distance[r][c] + 1;
31 q.push({nr, nc});
32 }
33 }
34 }
35
36 // Use max-heap for Dijkstra's algorithm to find the path with the max safeness factor
37 vector<vector<int>> maxSafeness(n, vector<int>(n, -1));
38 priority_queue<pair<int, pair<int, int>>> pq;
39 pq.push({distance[0][0], {0, 0}});
40 maxSafeness[0][0] = distance[0][0];
41
42 while (!pq.empty()) {
43 auto [safeness, pos] = pq.top(); pq.pop();
44 auto [r, c] = pos;
45
46 for (auto& dir : directions) {
47 int nr = r + dir[0], nc = c + dir[1];
48 if (nr >= 0 && nr < n && nc >= 0 && nc < n) {
49 int newSafeness = min(safeness, distance[nr][nc]);
50 if (newSafeness > maxSafeness[nr][nc]) {
51 maxSafeness[nr][nc] = newSafeness;
52 pq.push({newSafeness, {nr, nc}});
53 }
54 }
55 }
56 }
57
58 return maxSafeness[n-1][n-1];
59}
60
61int main() {
62 vector<vector<int>> grid = {{0, 0, 1}, {0, 0, 0}, {0, 0, 0}};
63 cout << maxSafenessFactor(grid) << endl; // Output: 2
64 return 0;
65}
66
This C++ solution employs a BFS to determine the minimum Manhattan distance from every cell to any thief. A priority queue (max-heap) then executes Dijkstra's algorithm to ascertain the path with the maximum safeness factor to the target cell.
This approach considers processing from both the starting and ending points in a bidirectional BFS style, potentially meeting in the middle for optimized distance calculations and safeness factor determination.
Time Complexity: O(n2) due to simultaneous BFS processing.
Space Complexity: O(n2) as distances from both ends are computed.
1import java.util.*;
2
3public class SafestPathFinder {
4 private static final int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
5
6 public int bidirectionalSafenessFactor(int[][] grid) {
7 int n = grid.length;
8 int[][] distFromStart = new int[n][n];
9 int[][] distFromEnd = new int[n][n];
10 for (int[] row : distFromStart) Arrays.fill(row, Integer.MAX_VALUE);
11 for (int[] row : distFromEnd) Arrays.fill(row, Integer.MAX_VALUE);
12
13 Queue<int[]> startQueue = new LinkedList<>();
14 startQueue.offer(new int[]{0, 0});
15 distFromStart[0][0] = 0;
16
17 Queue<int[]> endQueue = new LinkedList<>();
18 endQueue.offer(new int[]{n - 1, n - 1});
19 distFromEnd[n - 1][n - 1] = 0;
20
21 while (!startQueue.isEmpty() || !endQueue.isEmpty()) {
22 if (!startQueue.isEmpty()) {
23 int[] pos = startQueue.poll();
24 int r = pos[0], c = pos[1];
25 for (int[] dir : directions) {
26 int nr = r + dir[0], nc = c + dir[1];
27 if (nr >= 0 && nr < n && nc >= 0 && nc < n && distFromStart[nr][nc] == Integer.MAX_VALUE) {
28 distFromStart[nr][nc] = distFromStart[r][c] + 1;
29 startQueue.offer(new int[]{nr, nc});
30 }
31 }
32 }
33
34 if (!endQueue.isEmpty()) {
35 int[] pos = endQueue.poll();
36 int r = pos[0], c = pos[1];
37 for (int[] dir : directions) {
38 int nr = r + dir[0], nc = c + dir[1];
39 if (nr >= 0 && nr < n && nc >= 0 && nc < n && distFromEnd[nr][nc] == Integer.MAX_VALUE) {
40 distFromEnd[nr][nc] = distFromEnd[r][c] + 1;
41 endQueue.offer(new int[]{nr, nc});
42 }
43 }
44 }
45
46 // Checking overlap
47 for (int i = 0; i < n; ++i) {
48 for (int j = 0; j < n; ++j) {
49 if (distFromStart[i][j] != Integer.MAX_VALUE && distFromEnd[i][j] != Integer.MAX_VALUE) {
50 return distFromStart[i][j] + distFromEnd[i][j];
51 }
52 }
53 }
54 }
55
56 return -1;
57 }
58
59 public static void main(String[] args) {
60 SafestPathFinder spf = new SafestPathFinder();
61 int[][] grid = {{0, 0, 1}, {0, 0, 0}, {0, 0, 0}};
62 System.out.println(spf.bidirectionalSafenessFactor(grid)); // Output: Safeness factor
63 }
64}
65
The Java implementation employs bidirectional BFS from starting and ending corners, advancing until they converge. This optimized strategy minimizes redundant explorations and uncovers shared safe paths effectively.