Open In App

Minimum Time Required to Swim in Rising Water

Last Updated : 09 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

You have a grid, with dimensions of n x n where each element grid[i][j] represents the elevation at point (i, j). It started raining and at a given time t the water depth was t everywhere. You can swim from one square to another only if both squares have an elevation of t or less. You can swim infinite distances in zero time. You must stay within the grid boundaries. Your Task is to determine the minimum time needed to reach the bottom right square (n-1, n-1) if you start from the top left square (0, 0).

Examples:

Input: grid = [[0,2],[1,3]]
Output: 3
Explanation:

  • Initially at time 0 you find yourself located at grid position (0, 0).
  • You are limited in your movement options as all the neighbouring positions, in the four directions have an elevation than what is available at time t = 0.
  • Reaching point (1, 1) will only be possible after a waiting period of three units of time.
  • Once the water depth reaches 3 it becomes feasible to swim to any location, within the grid.

Input: grid = [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
Output: 16
Explanation:

  • The final route is depicted in the illustration provided.
  • It will be necessary to wait until time 16 for points (0, 0) and (4, 4) to become interconnected.

Approach: To solve the problem follow the below idea.

We can use Binary search to find the best time for traveling across a grid due to rain water. The main function, which is based on Depth First Search (DFS) checks whether or not you can travel from (0,0) to (n-1,n-1) with a given time limit. The binary search gradually narrows down the time range focusing on finding the minimum amount of time needed for a journey from the starting point, to the destination. This approach reduces the complexity of time calculations.

To solve the problem follow the below steps:

  1. Start by setting a value (l) as the elevation of the starting point and a high value (h), as the possible elevation, in the grid.
  2. Set the result (res) to the elevation.
  3. Use Binary search to find an optimal elevation range.
  4. In each iteration use a function (possible) that uses Depth First Search (DFS) to check if it’s possible to reach the destination within a given time.
  5. Adjust the search space based on whether reaching the destination’s feasible or not.
  6. Finally return the time found.

Below is the implementation of above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
int n;
int dx[4] = { 1, 0, 0, -1 };
int dy[4] = { 0, 1, -1, 0 };
bool possible(int i, int j, vector<vector<int> >& grid,
              int time, vector<vector<bool> >& vis) // DFS
{
    if (i < 0 || j < 0 || i >= n || j >= n
        || grid[i][j] > time || vis[i][j])
        return false;
    vis[i][j] = true;
    if (i == n - 1 && j == n - 1)
        return true;
    int x = grid[i][j];
    bool res = false;
    for (int k = 0; k < 4; k++) {
        res = res
              || possible(i + dx[k], j + dy[k], grid, time,
                          vis);
    }
    return res;
}
int swimInWater(vector<vector<int> >& grid)
{
    n = grid.size();
    int l = grid[0][0], h = 1e9;
    int res = h;
    while (l <= h) // Binary Search
    {
        int mid = (l + h) / 2;
        vector<vector<bool> > vis(n, vector<bool>(n));
        if (possible(0, 0, grid, mid, vis)) {
            res = mid;
            h = mid - 1;
        }
        else
            l = mid + 1;
    }
    return res;
}
 
int main()
{
 
    vector<vector<int> > grid1 = { { 0, 2 }, { 1, 3 } };
 
    int result = swimInWater(grid1);
    cout << result << endl;
 
    return 0;
}


Java




import java.util.Arrays;
 
public class Main {
    static int n;
    static int[] dx = {1, 0, 0, -1};
    static int[] dy = {0, 1, -1, 0};
 
    // DFS function
    static boolean possible(int i, int j, int[][] grid, int time, boolean[][] vis) {
        if (i < 0 || j < 0 || i >= n || j >= n || grid[i][j] > time || vis[i][j])
            return false;
 
        vis[i][j] = true;
 
        if (i == n - 1 && j == n - 1)
            return true;
 
        boolean res = false;
 
        for (int k = 0; k < 4; k++) {
            res = res || possible(i + dx[k], j + dy[k], grid, time, vis);
        }
 
        return res;
    }
 
    static int swimInWater(int[][] grid) {
        n = grid.length;
        int l = grid[0][0], h = 1_000_000_000;
        int res = h;
 
        while (l <= h) { // Binary Search
            int mid = (l + h) / 2;
            boolean[][] vis = new boolean[n][];
 
            for (int i = 0; i < n; i++) {
                vis[i] = new boolean[n];
            }
 
            if (possible(0, 0, grid, mid, vis)) {
                res = mid;
                h = mid - 1;
            } else {
                l = mid + 1;
            }
        }
 
        return res;
    }
 
    public static void main(String[] args) {
        int[][] grid1 = new int[][]{{0, 2}, {1, 3}};
 
        int result = swimInWater(grid1);
        System.out.println(result);
    }
}


Python3




n = 0
dx = [1, 0, 0, -1]
dy = [0, 1, -1, 0]
 
 
def possible(i, j, grid, time, vis):
    global n
 
    if i < 0 or j < 0 or i >= n or j >= n or grid[i][j] > time or vis[i][j]:
        return False
 
    vis[i][j] = True
 
    if i == n - 1 and j == n - 1:
        return True
 
    res = False
    for k in range(4):
        res = res or possible(i + dx[k], j + dy[k], grid, time, vis)
 
    return res
 
 
def swimInWater(grid):
    global n
    n = len(grid)
    l = grid[0][0]
    h = 1e9
    res = h
 
    while l <= h:  # Binary Search
        mid = (l + h) // 2
        vis = [[False for _ in range(n)] for _ in range(n)]
 
        if possible(0, 0, grid, mid, vis):
            res = mid
            h = mid - 1
        else:
            l = mid + 1
 
    return res
 
 
# Input
grid1 = [[0, 2], [1, 3]]
 
# Function Call
result = swimInWater(grid1)
print(result)


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static int n;
    static int[] dx = { 1, 0, 0, -1 };
    static int[] dy = { 0, 1, -1, 0 };
 
    // DFS function
    static bool Possible(int i, int j, int[][] grid, int time, bool[][] vis)
    {
        if (i < 0 || j < 0 || i >= n || j >= n || grid[i][j] > time || vis[i][j])
            return false;
         
        vis[i][j] = true;
 
        if (i == n - 1 && j == n - 1)
            return true;
 
         
        bool res = false;
 
        for (int k = 0; k < 4; k++)
        {
            res = res || Possible(i + dx[k], j + dy[k], grid, time, vis);
        }
 
        return res;
    }
 
    static int SwimInWater(int[][] grid)
    {
        n = grid.Length;
        int l = grid[0][0], h = 1_000_000_000;
        int res = h;
 
        while (l <= h) // Binary Search
        {
            int mid = (l + h) / 2;
            bool[][] vis = new bool[n][];
 
            for (int i = 0; i < n; i++)
            {
                vis[i] = new bool[n];
            }
 
            if (Possible(0, 0, grid, mid, vis))
            {
                res = mid;
                h = mid - 1;
            }
            else
            {
                l = mid + 1;
            }
        }
 
        return res;
    }
 
    static void Main()
    {
        int[][] grid1 = new int[][] { new int[] { 0, 2 }, new int[] { 1, 3 } };
 
        int result = SwimInWater(grid1);
        Console.WriteLine(result);
    }
}
// This code is contributed by shivamgupta0987654321


Javascript




// javaScript code for the above approach
 
let n;
const dx = [1, 0, 0, -1];
const dy = [0, 1, -1, 0];
 
function possible(i, j, grid, time, vis) {
    if (i < 0 || j < 0 || i >= n || j >= n || grid[i][j] > time || vis[i][j]) {
        return false;
    }
    vis[i][j] = true;
    if (i === n - 1 && j === n - 1) {
        return true;
    }
    let res = false;
    for (let k = 0; k < 4; k++) {
        res = res || possible(i + dx[k], j + dy[k], grid, time, vis);
    }
    return res;
}
 
function swimInWater(grid) {
    n = grid.length;
    let l = grid[0][0], h = 1e9;
    let res = h;
    // Binary Search
    while (l <= h) {
        let mid = Math.floor((l + h) / 2);
        let vis = new Array(n).fill(false).map(() => new Array(n).fill(false));
        if (possible(0, 0, grid, mid, vis)) {
            res = mid;
            h = mid - 1;
        }
        else {
            l = mid + 1;
        }
    }
    return res;
}
 
let grid1 = [
    [0, 2],
    [1, 3]
];
 
let result = swimInWater(grid1);
console.log(result);


Output

3









Time Complexity: O(N2 log(max_elevation – min_elevation))
Auxiliary Space: O(N^2).



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads