No results found for the specified position. Find the path with minimum effort. JavaScript Advanced Level Binary Search Mock Interview

MockQuestions

JavaScript Advanced Level Binary Search Mock Interview

Question 2 of 2 for our JavaScript Advanced Level Binary Search Mock Interview

Get More Information About Our JavaScript Advanced Level Binary Search Interview Questions

Question 2 of 2

Find the path with minimum effort.

This question focuses on the developer's knowledge of JavaScript binary search and loops.

You are given 2-D matrix heights for size n x m. A hiker is at the top-left cell (0, 0) (cells are 0-indexed). Her target is to reach the bottom-right of the cell (n - 1, m - 1). She can move either up, down, left or right from a cell. Your task is to find minimum effort to reach the destination cell. The effort of a path to the destination is the maximum absolute difference of their heights between two consecutive cells of the path.

/*Example*/

Given matrix-
[[1, 2, 2],
 [3, 8, 2],
 [5, 3, 5]]
	expected output = 2
	explanation:- 	The path 1 -> 2 -> 2 -> 2 -> 5 has an effort of 3.
The path 1 -> 3 -> 5 -> 3 -> 5 has an effort of 2.

Definitions:
● maximum absolute difference for the path 3 -> 4 -> 2 is maxOf(4 - 3, 4 - 2) = maxOf(1, 2) = 2
● maximum absolute difference for the path 1 -> 3 -> 5 -> 3 -> 5 is maxOf(2, 2, 2, 2) = 2
● maximum absolute difference for the path 1 -> 2 -> 2 -> 2 -> 5 is maxOf(1, 0, 0, 3) = 3

Constraints:
● 1 <= n, m <= 100
● 1 <= heights[i][j] <= 106

Solution:

We can use binary search to solve this problem. If we carefully observe, below the minimum effort, there is no way to reach the destination. Let’s say the minimum effort required is min. If we are asked:
● Can we reach our destination with an effort of less than min? The answer is definitely no.
● Can we reach our destination with an effort greater than or equal to min? The answer is definitely yes.

0 1 … min - 1 min min + 1 … max-possible
F F F F T T T T

We can do a binary search from 0 to max-possible. The value of max-possible will be the maximum height of a cell in the given matrix. We have a function that can reach answers the two questions above. It will return true if the effort passed is greater than or equal to min, false otherwise.

In the 'canReach' function, we will do DFS to at least one path using which we can reach the destination with given effort. We will maintain a 2-D array visited to check which nodes we have visited. We will start from the cell (0, 0). We will explore all the neighboring cells of the current cell viz. up, down, left, and right. While exploring a neighbouring cell, we will check if it is visited earlier. If it is not visited, we will check if the absolute height difference between the current cell and the neighboring cell is permitted using an impermissible function (i.e. check if less than given effort). If it is not permitted, we will not do DFS on this cell, because any path will not be possible through this cell. If it is permitted, we will do DFS on this cell and will explore its neighboring cells. If we have reached the destination cell, we simply return true, because there was at least one path using which we could reach the destination with given effort.

/**
 * @param {number[][]} heights
 * @return {number}
 */
function findMinimumEffort(heights) {
    let left = 0
    let right = 0
    
    for (const row of heights) {
        right = Math.max(right, Math.max(...row))
    }
    
    while(left < right) {
        let mid = (left + right) / 2
        mid = Math.floor(mid)
        
        if (canReach(mid, heights)) {
            right = mid
        } else {
            left = mid + 1
        }
    }
    
    return left
}

function canReach(effort, heights) {
    const n = heights.length
    const m = heights[0].length
    
    let isPossible = false

    // initialize visited matrix of size n x m will all false
    const visited = new Array(n)
    for (let i = 0; i < n; i++) {
        visited[i] = new Array(m).fill(false)
    }
    
    // check if the consecutive cells effort less than
    // or equal to passed effort
    function isPermissible(i1, j1, i2, j2) {
        const h1 = heights[i1][j1]
        const h2 = heights[i2][j2]
        
        return Math.abs(h1 - h2) <= effort
    }

    function dfs(i, j) {
        // we have reached the destination cell
        // return true
        if (i === n - 1 && j === m - 1) {
            return true
        }

        visited[i][j] = true
        
        const up = i - 1
        const down = i + 1
        const left = j - 1
        const right = j + 1  
        
        // check if we can visit the up cell
        if (
            up >= 0 &&
            !visited[up][j] &&
            isPermissible(i, j, up, j)
        ) {
            isPossible = isPossible || dfs(up, j)
        }

        // check if we can visit the down cell
        if (
            down < n &&
            !visited[down][j] &&
            isPermissible(i, j, down, j)
        ) {
            isPossible = isPossible || dfs(down, j)
        }
        
        // check if we can visit the left cell
        if (
            left >= 0 &&
            !visited[i][left] &&
            isPermissible(i, j, i, left)
        ) {
            isPossible = isPossible || dfs(i, left)
        }

        // check if we can visit the right cell
        if (
            right < m &&
            !visited[i][right] &&
            isPermissible(i, j, i, right)
        ) {
            isPossible = isPossible || dfs(i, right)
        }
        
        return isPossible
    }
    
    return dfs(0, 0)
}

Time complexity- O(n * m * log(106))
Space complexity- O(n * m)

Written by on May 22nd, 2021

Next Question

How to Answer: Find the path with minimum effort.

Advice and answer examples written specifically for a JavaScript Advanced Level Binary Search job interview.

  • 2. Find the path with minimum effort.

      This question focuses on the developer's knowledge of JavaScript binary search and loops.

      You are given 2-D matrix heights for size n x m. A hiker is at the top-left cell (0, 0) (cells are 0-indexed). Her target is to reach the bottom-right of the cell (n - 1, m - 1). She can move either up, down, left or right from a cell. Your task is to find minimum effort to reach the destination cell. The effort of a path to the destination is the maximum absolute difference of their heights between two consecutive cells of the path.

      /*Example*/
      
      Given matrix-
      [[1, 2, 2],
       [3, 8, 2],
       [5, 3, 5]]
      	expected output = 2
      	explanation:- 	The path 1 -> 2 -> 2 -> 2 -> 5 has an effort of 3.
      The path 1 -> 3 -> 5 -> 3 -> 5 has an effort of 2.

      Definitions:
      ● maximum absolute difference for the path 3 -> 4 -> 2 is maxOf(4 - 3, 4 - 2) = maxOf(1, 2) = 2
      ● maximum absolute difference for the path 1 -> 3 -> 5 -> 3 -> 5 is maxOf(2, 2, 2, 2) = 2
      ● maximum absolute difference for the path 1 -> 2 -> 2 -> 2 -> 5 is maxOf(1, 0, 0, 3) = 3

      Constraints:
      ● 1 <= n, m <= 100
      ● 1 <= heights[i][j] <= 106

      Solution:

      We can use binary search to solve this problem. If we carefully observe, below the minimum effort, there is no way to reach the destination. Let’s say the minimum effort required is min. If we are asked:
      ● Can we reach our destination with an effort of less than min? The answer is definitely no.
      ● Can we reach our destination with an effort greater than or equal to min? The answer is definitely yes.

      0 1 … min - 1 min min + 1 … max-possible
      F F F F T T T T

      We can do a binary search from 0 to max-possible. The value of max-possible will be the maximum height of a cell in the given matrix. We have a function that can reach answers the two questions above. It will return true if the effort passed is greater than or equal to min, false otherwise.

      In the 'canReach' function, we will do DFS to at least one path using which we can reach the destination with given effort. We will maintain a 2-D array visited to check which nodes we have visited. We will start from the cell (0, 0). We will explore all the neighboring cells of the current cell viz. up, down, left, and right. While exploring a neighbouring cell, we will check if it is visited earlier. If it is not visited, we will check if the absolute height difference between the current cell and the neighboring cell is permitted using an impermissible function (i.e. check if less than given effort). If it is not permitted, we will not do DFS on this cell, because any path will not be possible through this cell. If it is permitted, we will do DFS on this cell and will explore its neighboring cells. If we have reached the destination cell, we simply return true, because there was at least one path using which we could reach the destination with given effort.

      /**
       * @param {number[][]} heights
       * @return {number}
       */
      function findMinimumEffort(heights) {
          let left = 0
          let right = 0
          
          for (const row of heights) {
              right = Math.max(right, Math.max(...row))
          }
          
          while(left < right) {
              let mid = (left + right) / 2
              mid = Math.floor(mid)
              
              if (canReach(mid, heights)) {
                  right = mid
              } else {
                  left = mid + 1
              }
          }
          
          return left
      }
      
      function canReach(effort, heights) {
          const n = heights.length
          const m = heights[0].length
          
          let isPossible = false
      
          // initialize visited matrix of size n x m will all false
          const visited = new Array(n)
          for (let i = 0; i < n; i++) {
              visited[i] = new Array(m).fill(false)
          }
          
          // check if the consecutive cells effort less than
          // or equal to passed effort
          function isPermissible(i1, j1, i2, j2) {
              const h1 = heights[i1][j1]
              const h2 = heights[i2][j2]
              
              return Math.abs(h1 - h2) <= effort
          }
      
          function dfs(i, j) {
              // we have reached the destination cell
              // return true
              if (i === n - 1 && j === m - 1) {
                  return true
              }
      
              visited[i][j] = true
              
              const up = i - 1
              const down = i + 1
              const left = j - 1
              const right = j + 1  
              
              // check if we can visit the up cell
              if (
                  up >= 0 &&
                  !visited[up][j] &&
                  isPermissible(i, j, up, j)
              ) {
                  isPossible = isPossible || dfs(up, j)
              }
      
              // check if we can visit the down cell
              if (
                  down < n &&
                  !visited[down][j] &&
                  isPermissible(i, j, down, j)
              ) {
                  isPossible = isPossible || dfs(down, j)
              }
              
              // check if we can visit the left cell
              if (
                  left >= 0 &&
                  !visited[i][left] &&
                  isPermissible(i, j, i, left)
              ) {
                  isPossible = isPossible || dfs(i, left)
              }
      
              // check if we can visit the right cell
              if (
                  right < m &&
                  !visited[i][right] &&
                  isPermissible(i, j, i, right)
              ) {
                  isPossible = isPossible || dfs(i, right)
              }
              
              return isPossible
          }
          
          return dfs(0, 0)
      }

      Time complexity- O(n * m * log(106))
      Space complexity- O(n * m)

      Written by Jennie Taylor on May 22nd, 2021