Talentd
FleetCode
Make and follow sheets.Sign in

Disconnect Path in a Binary Matrix by at Most One Flip solution and explanation

MediumArrayBreadth-First SearchDepth-First SearchDynamic Programming7 min read28.4% acceptanceUpdated 9 Apr 2026
Disconnect Path in a Binary Matrix by at Most One Flip | Biweekly Contest 97 | LeetcodecodingMohan · 9:14 · 2K viewsWatch on YouTube
6 more videos on this problem
  1. Disconnect Path in a Binary Matrix by at Most One Flip | Biweekly Contest 97 | LeetcodecodingMohan · 9:14 · 2K views
  2. 2556. Disconnect Path in a Binary Matrix by at Most One Flip | LeetCodeDeep Tech · 10:32 · 1K views
  3. 2556. Disconnect Path in a Binary Matrix by at Most One Flip | Leetcode BiWeekly Contest 97 | DFSTech Courses · 8:18 · 867 views
  4. 2556. Disconnect Path in a Binary Matrix by at Most One Flip (Leetcode Hard)Programming Live with Larry · 28:17 · 669 views
  5. 【每日一题】LeetCode 2556. Disconnect Path in a Binary Matrix by at Most One FlipHuifeng Guan · 26:15 · 480 views
  6. Leetcode 2556. Disconnect Path in a Binary Matrix by at Most One FlipElite Code · 30:42 · 338 views
  7. Disconnect Path in a Binary Matrix by at Most One Flip | Leetcode Biweekly Contest 97 | BFS, GraphExplore with Gyani · 15:01 · 337 views

The problem

You are given a 0-indexed m x n binary matrix grid. You can move from a cell (row, col) to any of the cells (row + 1, col) or (row, col + 1) that has the value 1. The matrix is disconnected if there is no path from (0, 0) to (m - 1, n - 1).

You can flip the value of at most one (possibly none) cell. You cannot flip the cells (0, 0) and (m - 1, n - 1).

Return true if it is possible to make the matrix disconnect or false otherwise.

Note that flipping a cell changes its value from 0 to 1 or from 1 to 0.

Example 1:

Input: grid = [[1,1,1],[1,0,0],[1,1,1]]
Output: true
Explanation: We can change the cell shown in the diagram above. There is no path from (0, 0) to (2, 2) in the resulting grid.

Example 2:

Input: grid = [[1,1,1],[1,0,1],[1,1,1]]
Output: false
Explanation: It is not possible to change at most one cell such that there is not path from (0, 0) to (2, 2).

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 1000
  • 1 <= m * n <= 105
  • grid[i][j] is either 0 or 1.
  • grid[0][0] == grid[m - 1][n - 1] == 1

Approach overview

Problem Overview: You are given a binary matrix where 1 represents a valid cell and 0 represents a blocked cell. Starting from the top‑left corner, you can only move right or down. The task is to determine whether flipping at most one 1 to 0 can disconnect all paths from the start cell to the bottom‑right cell.

Approach 1: BFS/DFS to Check and Remove One Path (O(m*n) time, O(m*n) space)

Run a DFS or BFS from (0,0) to see if a valid path to (m-1,n-1) exists. If no path exists, the grid is already disconnected, so return true. Otherwise, trace one discovered path and temporarily flip its intermediate cells to 0. Then run the traversal again. If another path still reaches the destination, the grid cannot be disconnected with a single flip. If no second path exists, one flipped cell along the original path is enough to break connectivity.

The key insight: if two independent paths exist that do not rely on the same intermediate cell, removing one cell will not disconnect the grid. Removing the cells of the first discovered path tests whether an alternative route exists. This technique relies heavily on grid traversal using Depth-First Search or Breadth-First Search.

Approach 2: Track Reachable and Critical Cells Separately (Dynamic Programming) (O(m*n) time, O(m*n) space)

Compute reachability from the start and from the end separately. A forward DP or BFS marks cells reachable from (0,0), while a reverse traversal marks cells that can reach (m-1,n-1). Any cell that appears in both sets lies on at least one valid path.

Next, count how many such cells appear on each "layer" defined by i + j. If a layer contains exactly one reachable cell that lies on every path, that cell becomes a critical bottleneck. Flipping it disconnects the grid. This method effectively identifies articulation-like points in the path structure using Dynamic Programming on a matrix.

Recommended for interviews: The DFS/BFS path-removal approach is the most common interview solution. It is simple, runs in O(m*n), and demonstrates strong understanding of grid traversal and path uniqueness. The DP reachability method shows deeper insight into path structure and critical cells but is slightly harder to reason about under interview pressure.

Approach 1: BFS/DFS to Check Initial Connectivity

Perform a BFS or DFS from the starting point (0, 0) to determine if there is a path to (m-1, n-1). Record reachable cells. If these cells all remain connected even after a potential flip, then the grid cannot be disconnected. Otherwise, assess if flipping a single cell can break the connection.

def is_possible_to_disconnect(grid):
    from collections import deque
    m, n = len(grid), len(grid[0])
    if grid[0][0] == 0 or grid[m-1][n-1] == 0:
        return False
    
    # BFS to see if there's an original path
    def bfs():
        q = deque([(0, 0)])
        visited = set([(0, 0)])
        while q:
            x, y = q.popleft()
            if (x, y) == (m-1, n-1):
                return True
            for dx, dy in [(1, 0), (0, 1)]:
                nx, ny = x + dx, y + dy
                if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 1 and (nx, ny) not in visited:
                    visited.add((nx, ny))
                    q.append((nx, ny))
        return False

    if not bfs():
        return True  # Already disconnected

    # Try flipping positions adjacent to the path
    for i in range(m):
        for j in range(n):
            if grid[i][j] == 0:
                grid[i][j] = 1
                if not bfs():
                    return True
                grid[i][j] = 0

    return False
function isPossibleToDisconnect(grid) {
    const m = grid.length, n = grid[0].length;
    if (grid[0][0] === 0 || grid[m-1][n-1] === 0) return true;

    function bfs() {
        const queue = [[0, 0]];
        const visited = new Set(["0,0"]);
        
        while (queue.length > 0) {
            const [x, y] = queue.shift();
            if (x === m-1 && y === n-1) return true;
            for (const [dx, dy] of [[1, 0], [0, 1]]) {
                const nx = x + dx, ny = y + dy;
                if (0 <= nx && nx < m && 0 <= ny && ny < n && grid[nx][ny] === 1 && !visited.has(`${nx},${ny}`)) {
                    visited.add(`${nx},${ny}`);
                    queue.push([nx, ny]);
                }
            }
        }
        return false;
    }

    if (!bfs()) return true;

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === 0) {
                grid[i][j] = 1;
                if (!bfs()) return true;
                grid[i][j] = 0;
            }
        }
    }
    return false;
}

The function uses a BFS to check if the grid is initially connected from (0, 0) to (m-1, n-1). If it is connected, the code then explores flipping each 0 cell adjacent to the connected path to determine if the grid can be disconnected by such a flip.

Complexity
  • Time Complexity: O(m * n), where m and n are rows and columns.
  • Space Complexity: O(m * n), due to the queue and visited set.
Try this approach in the editor

Approach 2: Track Reachable and Critical Cells Separately

Identify critical cells that are necessary for maintaining a path from (0, 0) to (m-1, n-1). Implement union-find to manage connectivity dynamically, and then flip cells to test disconnection potential while keeping track of reachability separately.

import java.util.*;

public class DisconnectPath {
    public static boolean checkInitialConnectivity(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        Queue<int[]> queue = new LinkedList<>();
        boolean[][] visited = new boolean[m][n];
        queue.offer(new int[]{0, 0});
        visited[0][0] = true;
        
        while (!queue.isEmpty()) {
            int[] cell = queue.poll();
            int x = cell[0], y = cell[1];
            if (x == m - 1 && y == n - 1) return true;
            for (int[] dir : new int[][]{{1, 0}, {0, 1}}) {
                int nx = x + dir[0], ny = y + dir[1];
                if (nx < m && ny < n && grid[nx][ny] == 1 && !visited[nx][ny]) {
                    visited[nx][ny] = true;
                    queue.offer(new int[]{nx, ny});
                }
            }
        }
        return false;
    }

    public static boolean isPossibleToDisconnect(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        if (!checkInitialConnectivity(grid)) return true;

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 0) {
                    grid[i][j] = 1;
                    if (!checkInitialConnectivity(grid)) return true;
                    grid[i][j] = 0;
                }
            }
        }

        return false;
    }
}
#include <vector>
#include <queue>
using namespace std;

bool isPath(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();
    if (grid[0][0] == 0 || grid[m-1][n-1] == 0) return false;
    
    queue<pair<int, int>> q;
    vector<vector<bool>> visited(m, vector<bool>(n, false));
    q.push({0, 0});
    visited[0][0] = true;
    
    while (!q.empty()) {
        auto [x, y] = q.front(); q.pop();
        if (x == m - 1 && y == n - 1) return true;
        
        for (auto [dx, dy] : vector<pair<int, int>>{{1, 0}, {0, 1}}) {
            int nx = x + dx, ny = y + dy;
            if (nx < m && ny < n && grid[nx][ny] == 1 && !visited[nx][ny]) {
                visited[nx][ny] = true;
                q.push({nx, ny});
            }
        }
    }
    return false;
}

bool isPossibleToDisconnect(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();
    if (!isPath(grid)) return true;

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (grid[i][j] == 0) {
                grid[i][j] = 1;
                if (!isPath(grid)) return true;
                grid[i][j] = 0;
            }
        }
    }

    return false;
}

The Java solution separates the path-checking logic into a helper function to streamline the control flow. By seeing each step compartmentalized, its structure facilitates the handoff of logic across the main and helper methods, embracing standard Java practices.

Complexity
  • Time Complexity: O(m * n), with BFS evaluating each cell's connectivity once.
  • Space Complexity: O(m * n), from queues/lists used to track cell exploration.
Try this approach in the editor

Approach 3: Two DFS Traversals

First, we perform a DFS traversal to determine whether there is a path from (0, 0) to (m - 1, n - 1), and we denote the result as a. During the DFS process, we set the value of the visited cells to 0 to prevent revisiting.

Next, we set the values of (0, 0) and (m - 1, n - 1) to 1, and perform another DFS traversal to determine whether there is a path from (0, 0) to (m - 1, n - 1), and we denote the result as b. During the DFS process, we set the value of the visited cells to 0 to avoid revisiting.

Finally, if both a and b are true, we return false, otherwise, we return true.

The time complexity is O(m times n), and the space complexity is O(m times n). Where m and n are the number of rows and columns of the matrix, respectively.

function isPossibleToCutPath(grid: number[][]): boolean {
    const m = grid.length;
    const n = grid[0].length;

    const dfs = (i: number, j: number): boolean => {
        if (i >= m || j >= n || grid[i][j] !== 1) {
            return false;
        }
        grid[i][j] = 0;
        if (i === m - 1 && j === n - 1) {
            return true;
        }
        return dfs(i + 1, j) || dfs(i, j + 1);
    };
    const a = dfs(0, 0);
    grid[0][0] = 1;
    grid[m - 1][n - 1] = 1;
    const b = dfs(0, 0);
    return !(a && b);
}
func isPossibleToCutPath(grid [][]int) bool {
	m, n := len(grid), len(grid[0])
	var dfs func(i, j int) bool
	dfs = func(i, j int) bool {
		if i >= m || j >= n || grid[i][j] == 0 {
			return false
		}
		if i == m-1 && j == n-1 {
			return true
		}
		grid[i][j] = 0
		return dfs(i+1, j) || dfs(i, j+1)
	}
	a := dfs(0, 0)
	grid[0][0], grid[m-1][n-1] = 1, 1
	b := dfs(0, 0)
	return !(a && b)
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
BFS/DFS to Check Initial Connectivity
  • Time Complexity: O(m * n), where m and n are rows and columns.
  • Space Complexity: O(m * n), due to the queue and visited set.
Track Reachable and Critical Cells Separately
  • Time Complexity: O(m * n), with BFS evaluating each cell's connectivity once.
  • Space Complexity: O(m * n), from queues/lists used to track cell exploration.
Two DFS Traversals–

Complexity analysis

ApproachTimeSpaceWhen to Use
DFS/BFS Path Detection and RemovalO(m*n)O(m*n)General interview solution; simple traversal and easy to implement
Reachability + Critical Layer Tracking (DP)O(m*n)O(m*n)When analyzing path bottlenecks or identifying critical cells across all paths

Frequently asked questions

Is Disconnect Path in a Binary Matrix by at Most One Flip easy or hard?

This problem is rated Medium on LeetCode but feels tricky because it mixes grid traversal with reasoning about multiple paths. The implementation itself is straightforward once the insight about testing for a second independent path is understood.

Disconnect Path in a Binary Matrix by at Most One Flip Python/Java solution

Python and Java implementations typically use DFS or BFS for grid traversal. The algorithm first finds one path from start to end, blocks that path, and runs the search again. If the second search fails to reach the target, flipping one cell successfully disconnects the grid.

How to solve Disconnect Path in a Binary Matrix by at Most One Flip in O(m*n)?

First run DFS or BFS to check if a path from the top-left to bottom-right exists. If no path exists, return true. If a path exists, mark the cells of that path as blocked and run the traversal again. If the destination is still reachable, more than one independent path exists and one flip is insufficient; otherwise the grid becomes disconnected.

What is the best approach for Disconnect Path in a Binary Matrix by at Most One Flip?

The most practical approach uses DFS or BFS to find one valid path from the start to the end, temporarily removes that path, and then checks if another path still exists. If a second path is found, the grid cannot be disconnected with one flip. If no second path exists, flipping a cell from the first path breaks connectivity. This solution runs in O(m*n) time.

Is Disconnect Path in a Binary Matrix by at Most One Flip asked at Google/Amazon/Meta?

Grid traversal and path‑disconnection problems appear frequently in interviews at companies like Google, Amazon, and Meta. Variants involving DFS, BFS, or identifying critical cells in a grid are common because they test graph modeling and algorithmic reasoning.

What data structure is used in Disconnect Path in a Binary Matrix by at Most One Flip?

The core data structures are a matrix for the grid, a visited structure for traversal, and either a recursion stack (DFS) or queue (BFS). Some optimized solutions also use dynamic programming arrays to track cells reachable from the start and from the end.

What is the time complexity of Disconnect Path in a Binary Matrix by at Most One Flip?

Both common solutions run in O(m*n) time where m and n are the grid dimensions. The algorithm performs at most two full traversals of the matrix using DFS or BFS. Space complexity is also O(m*n) due to recursion stack or visited tracking structures.

Comments

Now write it yourselfClose this page and solve Disconnect Path in a Binary Matrix by at Most One Flip in the editor, without looking.
Practise Disconnect Path in a Binary Matrix by at Most One Flip