Submatrix with corners as 1

Last Updated : 16 Feb, 2026

Given a binary matrix containing only 0s and 1s. The task is to check whether there exists a rectangle or square submatrix of size at least 2 × 2 such that all four corners of that submatrix are 1.
This means we must find four positions in the matrix (top-left, top-right, bottom-left, and bottom-right, that are all 1, and they must form the corners of a valid rectangle).

Examples: 

Input: mat[][] = [[1, 0, 0, 1, 0],
[0, 0, 1, 0, 1],
[0, 0, 0, 1, 0],
[1, 0, 1, 0, 1]]
Output : true
Explanation : There exists the below submatrix
1 0 1
0 1 0
1 0 1

Input: mat[][] = [[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 0, 1],
[1, 1, 1, 1]]
Output : false
Explanation : There exists the below submatrix:
1 1 1 1
1 0 0 1
1 0 0 1
1 1 1 1

Input: mat[][] = [[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 1, 0, 1]]
Output : false
Explanation: There is no rectangle with all corners as 1.

Try It Yourself
redirect icon

[Naive Approach] Check Every Submatrix - O((n^2)*(m^2)) Time and O(1) Space

The idea is to check all possible submatrices of size at least 2 × 2 by iterating through every pair of rows and every pair of columns. For each such combination (quadruple), we verify if the four corners of the submatrix are all 1s. If such a rectangle is found, we return true immediately. This approach ensures that we don't miss any valid configuration.

C++
// C++ program to check if there exists a submatrix
// with all 1s at the corners using Naive Approach
#include <bits/stdc++.h>
using namespace std;

// Function to check for a rectangle with corners as 1
bool ValidCorner(vector<vector<int>> &mat) {
    
    int rows = mat.size();
    int cols = mat[0].size();

    // Iterate over all pairs of rows
    for (int top = 0; top < rows - 1; top++) {
        for (int bottom = top + 1; bottom < rows; bottom++) {

            // Iterate over all pairs of columns
            for (int left = 0; left < cols - 1; left++) {
                for (int right = left + 1; right < cols; right++) {

                    // Check all four corners of the submatrix
                    if (mat[top][left] == 1 && mat[top][right] == 1 &&
                        mat[bottom][left] == 1 && mat[bottom][right] == 1) {
                        return true;
                    }
                }
            }
        }
    }

    // No such rectangle found
    return false;
}

// Driver code
int main() {

    vector<vector<int>> mat = {
        {1, 0, 0, 1, 0},
        {0, 0, 1, 0, 1},
        {0, 0, 0, 1, 0},
        {1, 0, 1, 0, 1}
    };
    
    if (ValidCorner(mat)) {
        cout << "true";
    } 
    else {
        cout << "false";
    }

    return 0;
}
Java
// Java program to check if there exists a submatrix
// with all 1s at the corners using Naive Approach
class GfG {

    // Function to check for a rectangle with corners as 1
    static boolean ValidCorner(int[][] mat) {

        int rows = mat.length;
        int cols = mat[0].length;

        // Iterate over all pairs of rows
        for (int top = 0; top < rows - 1; top++) {
            for (int bottom = top + 1; bottom < rows; bottom++) {

                // Iterate over all pairs of columns
                for (int left = 0; left < cols - 1; left++) {
                    for (int right = left + 1; right < cols; right++) {

                        // Check all four corners of the submatrix
                        if (mat[top][left] == 1 && mat[top][right] == 1 &&
                            mat[bottom][left] == 1 && mat[bottom][right] == 1) {
                            return true;
                        }
                    }
                }
            }
        }

        // No such rectangle found
        return false;
    }

    public static void main(String[] args) {

        int[][] mat = {
            {1, 0, 0, 1, 0},
            {0, 0, 1, 0, 1},
            {0, 0, 0, 1, 0},
            {1, 0, 1, 0, 1}
        };

        
        System.out.print(ValidCorner(mat));
        
    }
}
Python
# Python program to check if there exists a submatrix
# with all 1s at the corners using Naive Approach

# Function to check for a rectangle with corners as 1
def ValidCorner(mat):

    rows = len(mat)
    cols = len(mat[0])

    # Iterate over all pairs of rows
    for top in range(rows - 1):
        for bottom in range(top + 1, rows):

            # Iterate over all pairs of columns
            for left in range(cols - 1):
                for right in range(left + 1, cols):

                    # Check all four corners of the submatrix
                    if (mat[top][left] == 1 and mat[top][right] == 1 and
                        mat[bottom][left] == 1 and mat[bottom][right] == 1):
                        return True

    # No such rectangle found
    return False

if __name__ == '__main__':

    mat = [
        [1, 0, 0, 1, 0],
        [0, 0, 1, 0, 1],
        [0, 0, 0, 1, 0],
        [1, 0, 1, 0, 1]
    ]
    
    if ValidCorner(mat):
        print("true")
    else:
        print("false")
C#
// C# program to check if there exists a submatrix
// with all 1s at the corners using Naive Approach
using System;

class GfG {

    // Function to check for a rectangle with corners as 1
    static bool ValidCorner(int[][] mat) {

        int rows = mat.Length;
        int cols = mat[0].Length;

        // Iterate over all pairs of rows
        for (int top = 0; top < rows - 1; top++) {
            for (int bottom = top + 1; bottom < rows; bottom++) {

                // Iterate over all pairs of columns
                for (int left = 0; left < cols - 1; left++) {
                    for (int right = left + 1; right < cols; right++) {

                        // Check all four corners of the submatrix
                        if (mat[top][left] == 1 && mat[top][right] == 1 &&
                            mat[bottom][left] == 1 && mat[bottom][right] == 1) {
                            return true;
                        }
                    }
                }
            }
        }

        // No such rectangle found
        return false;
    }

    static void Main() {

        int[][] mat = new int[][] {
            new int[] {1, 0, 0, 1, 0},
            new int[] {0, 0, 1, 0, 1},
            new int[] {0, 0, 0, 1, 0},
            new int[] {1, 0, 1, 0, 1}
        };
        
       
        if (ValidCorner(mat)) {
            Console.Write("true");
           
        } 
        else {
            Console.Write("false");
        }
    }
}
JavaScript
// JavaScript program to check if there exists a submatrix
// with all 1s at the corners using Naive Approach

// Function to check for a rectangle with corners as 1
function ValidCorner(mat) {

    let rows = mat.length;
    let cols = mat[0].length;

    // Iterate over all pairs of rows
    for (let top = 0; top < rows - 1; top++) {
        for (let bottom = top + 1; bottom < rows; bottom++) {

            // Iterate over all pairs of columns
            for (let left = 0; left < cols - 1; left++) {
                for (let right = left + 1; right < cols; right++) {

                    // Check all four corners of the submatrix
                    if (mat[top][left] === 1 && mat[top][right] === 1 &&
                        mat[bottom][left] === 1 && mat[bottom][right] === 1) {
                        return true;
                    }
                }
            }
        }
    }

    // No such rectangle found
    return false;
}

let mat = [
    [1, 0, 0, 1, 0],
    [0, 0, 1, 0, 1],
    [0, 0, 0, 1, 0],
    [1, 0, 1, 0, 1]
];

console.log(ValidCorner(mat))

Output
true

[Better Approach] Using Hashing - O(n*(m^2)) Time and O(n*m) Space

The idea is to use hashing to avoid checking every submatrix explicitly. We need to track column pairs with 1s in each row using a set. If the same pair of columns has 1s in more than one row, then a submatrix with all 1s at corners must exist. This works because repeating column pairs across rows form the top and bottom of a valid submatrix.

C++
// C++ program to check if there exists a submatrix
// with all 1s at the corners using Simple Hashing
#include <bits/stdc++.h>
using namespace std;

// Function to check for a rectangle with corners as 1
bool ValidCorner(vector<vector<int>> &mat) {
    
    int rows = mat.size();
    int cols = mat[0].size();

    // Hash set to store pairs of columns having 1 in a row
    unordered_set<string> seen;

    // Iterate through each row
    for (int i = 0; i < rows; i++) {

        // Check all column pairs where cell is 1
        for (int col1 = 0; col1 < cols - 1; col1++) {
            if (mat[i][col1] == 0) continue;

            for (int col2 = col1 + 1; col2 < cols; col2++) {
                if (mat[i][col2] == 0) continue;

                // Form a unique key from column pair
                string key = to_string(col1) + "," + to_string(col2);

                // If this pair seen before → rectangle exists
                if (seen.find(key) != seen.end()) {
                    return true;
                }

                // Otherwise store it
                seen.insert(key);
            }
        }
    }

    // No rectangle found
    return false;
}

// Driver code
int main() {

    vector<vector<int>> mat = {
        {1, 0, 0, 1, 0},
        {0, 0, 1, 0, 1},
        {0, 0, 0, 1, 0},
        {1, 0, 1, 0, 1}
    };

    if (ValidCorner(mat)) {
        cout << "true";
    } 
    else {
        cout << "false";
    }

    return 0;
}
Java
// Java program to check if there exists a submatrix
// with all 1s at the corners using Simple Hashing
import java.util.*;

class GfG {

    // Function to check for a rectangle with corners as 1
    static boolean ValidCorner(int[][] mat) {

        int rows = mat.length;
        int cols = mat[0].length;

        // Hash set to store pairs of columns having 1 in a row
        HashSet<String> seen = new HashSet<>();

        // Iterate through each row
        for (int i = 0; i < rows; i++) {

            // Check all column pairs where cell is 1
            for (int col1 = 0; col1 < cols - 1; col1++) {
                if (mat[i][col1] == 0) continue;

                for (int col2 = col1 + 1; col2 < cols; col2++) {
                    if (mat[i][col2] == 0) continue;

                    // Form a unique key from column pair
                    String key = col1 + "," + col2;

                    // If this pair seen before → rectangle exists
                    if (seen.contains(key)) {
                        return true;
                    }

                    // Otherwise store it
                    seen.add(key);
                }
            }
        }

        // No rectangle found
        return false;
    }

    // Driver code
    public static void main(String[] args) {

        int[][] mat = {
            {1, 0, 0, 1, 0},
            {0, 0, 1, 0, 1},
            {0, 0, 0, 1, 0},
            {1, 0, 1, 0, 1}
        };

        System.out.println(ValidCorner(mat));

    }
}
Python
# Python program to check if there exists a submatrix
# with all 1s at the corners using Simple Hashing

def ValidCorner(mat):

    rows = len(mat)
    cols = len(mat[0])

    # Hash set to store pairs of columns having 1 in a row
    seen = set()

    # Iterate through each row
    for i in range(rows):

        # Check all column pairs where cell is 1
        for col1 in range(cols - 1):
            if mat[i][col1] == 0:
                continue

            for col2 in range(col1 + 1, cols):
                if mat[i][col2] == 0:
                    continue

                # Form a unique key from column pair
                key = str(col1) + "," + str(col2)

                # If this pair seen before → rectangle exists
                if key in seen:
                    return True

                # Otherwise store it
                seen.add(key)

    # No rectangle found
    return False

# Driver code
if __name__ == "__main__":

    mat = [
        [1, 0, 0, 1, 0],
        [0, 0, 1, 0, 1],
        [0, 0, 0, 1, 0],
        [1, 0, 1, 0, 1]
    ]

    if ValidCorner(mat):
        print("true")
    else:
        print("false")
C#
// C# program to check if there exists a submatrix
// with all 1s at the corners using Simple Hashing
using System;
using System.Collections.Generic;

class GfG {

    // Function to check for a rectangle with corners as 1
    static bool ValidCorner(int[][] mat) {

        int rows = mat.Length;
        int cols = mat[0].Length;

        // Hash set to store pairs of columns having 1 in a row
        HashSet<string> seen = new HashSet<string>();

        // Iterate through each row
        for (int i = 0; i < rows; i++) {

            // Check all column pairs where cell is 1
            for (int col1 = 0; col1 < cols - 1; col1++) {
                if (mat[i][col1] == 0) continue;

                for (int col2 = col1 + 1; col2 < cols; col2++) {
                    if (mat[i][col2] == 0) continue;

                    // Form a unique key from column pair
                    string key = col1 + "," + col2;

                    // If this pair seen before → rectangle exists
                    if (seen.Contains(key)) {
                        return true;
                    }

                    // Otherwise store it
                    seen.Add(key);
                }
            }
        }

        // No rectangle found
        return false;
    }

    // Driver code
    public static void Main() {

        int[][] mat = {
            new int[] {1, 0, 0, 1, 0},
            new int[] {0, 0, 1, 0, 1},
            new int[] {0, 0, 0, 1, 0},
            new int[] {1, 0, 1, 0, 1}
        };
        
        
        if (ValidCorner(mat)) {
            Console.WriteLine("true");
        } 
        else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
// JavaScript program to check if there exists a submatrix
// with all 1s at the corners using Simple Hashing

function ValidCorner(mat) {

    let rows = mat.length;
    let cols = mat[0].length;

    // Hash set to store pairs of columns having 1 in a row
    let seen = new Set();

    // Iterate through each row
    for (let i = 0; i < rows; i++) {

        // Check all column pairs where cell is 1
        for (let col1 = 0; col1 < cols - 1; col1++) {
            if (mat[i][col1] === 0) continue;

            for (let col2 = col1 + 1; col2 < cols; col2++) {
                if (mat[i][col2] === 0) continue;

                // Form a unique key from column pair
                let key = col1 + "," + col2;

                // If this pair seen before → rectangle exists
                if (seen.has(key)) {
                    return true;
                }

                // Otherwise store it
                seen.add(key);
            }
        }
    }

    // No rectangle found
    return false;
}

// Driver code
let mat = [
    [1, 0, 0, 1, 0],
    [0, 0, 1, 0, 1],
    [0, 0, 0, 1, 0],
    [1, 0, 1, 0, 1]
];

console.log(ValidCorner(mat));

Output
true

[Expected Approach] Using Sparse-Dense Row Strategy

Instead of checking every possible rectangle directly, it optimizes the search by analyzing rows with 1s and checking for repeating column pairs. Rows are categorized as dense or sparse to reduce time complexity by using different strategies for each.

We can see that two rows share at least two common columns with 1s, then those column indices form the vertical sides of a rectangle, and the two rows form the horizontal sides. So, we only need to find such row pairs with common 1-columns at the same indices.

So, to Solve this, First processes each row to record the columns that have 1s. For sparse rows (having fewer 1s), it stores every unique pair of column indices and checks if the same pair appeared before — indicating a rectangle with a previous row. For dense rows (many 1s), it compares against all earlier rows to count how many 1-columns they share, and returns true if at least two are common.

C++
#include <vector>
#include <unordered_set>
#include <cmath>
#include<iostream>
using namespace std;

bool ValidCorner(vector<vector<int> >& mat){
    
    int n = mat.size();
    int m = mat[0].size();

    vector<vector<int>> rows(n);
    int totalOnes = 0;

    // collect columns with 1s
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j]) {
                rows[i].push_back(j);
                totalOnes++;
            }
        }
    }

    int threshold = sqrt(totalOnes);

    // pairSeen[c1][c2] = whether any previous row had both c1 and c2
    static bool pairSeen[205][205];
    memset(pairSeen, false, sizeof(pairSeen));

    // For dense rows: mark column presence
    vector<bool> present(m);

    for (int r = 0; r < n; r++) {

        // Dense row
        if ((int)rows[r].size() >= threshold) {
            fill(present.begin(), present.end(), false);
            for (int c : rows[r]) present[c] = true;

            // Check all column pairs directly
            for (int i = 0; i < m; i++) {
                if (!present[i]) continue;
                for (int j = i + 1; j < m; j++) {
                    if (present[j]) {
                        if (pairSeen[i][j])
                            return true;   // rectangle found
                        pairSeen[i][j] = true;
                    }
                }
            }
        }

        // Sparse row
        else {
            for (int i = 0; i < rows[r].size(); i++) {
                for (int j = i + 1; j < rows[r].size(); j++) {
                    int c1 = rows[r][i];
                    int c2 = rows[r][j];
                    if (pairSeen[c1][c2])
                        return true;       // rectangle found
                    pairSeen[c1][c2] = true;
                }
            }
        }
    }
    return false;
}
int main() {

    vector<vector<int>> mat = {
        {1, 0, 0, 1, 0},
        {0, 0, 1, 0, 1},
        {0, 0, 0, 1, 0},
        {1, 0, 1, 0, 1}
    };

    if (ValidCorner(mat)) {
        cout << "true";
    } 
    else {
        cout << "false";
    }

    return 0;
}
Java
import java.util.*;

class GfG {

    static boolean ValidCorner(int[][] mat) {

        int n = mat.length;
        int m = mat[0].length;

        List<List<Integer>> rows = new ArrayList<>();
        int totalOnes = 0;

        // collect columns with 1s
        for (int i = 0; i < n; i++) {
            List<Integer> cols = new ArrayList<>();
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1) {
                    cols.add(j);
                    totalOnes++;
                }
            }
            rows.add(cols);
        }

        int threshold = (int) Math.sqrt(totalOnes);

        // pairSeen[c1][c2] = whether any previous row had both c1 and c2
        boolean[][] pairSeen = new boolean[205][205];

        // For dense rows: mark column presence
        boolean[] present = new boolean[m];

        for (int r = 0; r < n; r++) {

            // Dense row
            if (rows.get(r).size() >= threshold) {
                Arrays.fill(present, false);
                for (int c : rows.get(r)) {
                    present[c] = true;
                }

                // Check all column pairs directly
                for (int i = 0; i < m; i++) {
                    if (!present[i]) continue;
                    for (int j = i + 1; j < m; j++) {
                        if (present[j]) {
                            if (pairSeen[i][j])
                                return true; // rectangle found
                            pairSeen[i][j] = true;
                        }
                    }
                }
            }

            // Sparse row
            else {
                List<Integer> row = rows.get(r);
                for (int i = 0; i < row.size(); i++) {
                    for (int j = i + 1; j < row.size(); j++) {
                        int c1 = row.get(i);
                        int c2 = row.get(j);
                        if (pairSeen[c1][c2])
                            return true; // rectangle found
                        pairSeen[c1][c2] = true;
                    }
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {1, 0, 0, 1, 0},
            {0, 0, 1, 0, 1},
            {0, 0, 0, 1, 0},
            {1, 0, 1, 0, 1}
        };

        System.out.println(ValidCorner(mat) ? "true" : "false");
    }
}
Python
import math

def ValidCorner(mat):

    n = len(mat)
    m = len(mat[0])

    rows = []
    totalOnes = 0

    # collect columns with 1s
    for i in range(n):
        cols = []
        for j in range(m):
            if mat[i][j] == 1:
                cols.append(j)
                totalOnes += 1
        rows.append(cols)

    threshold = int(math.sqrt(totalOnes))

    # pairSeen[c1][c2] = whether any previous row had both c1 and c2
    pairSeen = [[False] * 205 for _ in range(205)]

    # For dense rows: mark column presence
    present = [False] * m

    for r in range(n):

        # Dense row
        if len(rows[r]) >= threshold:
            for i in range(m):
                present[i] = False
            for c in rows[r]:
                present[c] = True

            # Check all column pairs directly
            for i in range(m):
                if not present[i]:
                    continue
                for j in range(i + 1, m):
                    if present[j]:
                        if pairSeen[i][j]:
                            return True  # rectangle found
                        pairSeen[i][j] = True

        # Sparse row
        else:
            row = rows[r]
            for i in range(len(row)):
                for j in range(i + 1, len(row)):
                    c1 = row[i]
                    c2 = row[j]
                    if pairSeen[c1][c2]:
                        return True  # rectangle found
                    pairSeen[c1][c2] = True

    return False

# Custom Input
if __name__ == "__main__":
    mat = [
        [1, 0, 0, 1, 0],
        [0, 0, 1, 0, 1],
        [0, 0, 0, 1, 0],
        [1, 0, 1, 0, 1]
    ]

    print("true" if ValidCorner(mat) else "false")
C#
using System;
using System.Collections.Generic;

class GfG {

    static bool ValidCorner(int[,] mat) {

        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        List<List<int>> rows = new List<List<int>>();
        int totalOnes = 0;

        // collect columns with 1s
        for (int i = 0; i < n; i++) {
            List<int> cols = new List<int>();
            for (int j = 0; j < m; j++) {
                if (mat[i, j] == 1) {
                    cols.Add(j);
                    totalOnes++;
                }
            }
            rows.Add(cols);
        }

        int threshold = (int)Math.Sqrt(totalOnes);

        // pairSeen[c1][c2] = whether any previous row had both c1 and c2
        bool[,] pairSeen = new bool[205, 205];

        // For dense rows: mark column presence
        bool[] present = new bool[m];

        for (int r = 0; r < n; r++) {

            // Dense row
            if (rows[r].Count >= threshold) {
                Array.Clear(present, 0, m);
                foreach (int c in rows[r]) {
                    present[c] = true;
                }

                // Check all column pairs directly
                for (int i = 0; i < m; i++) {
                    if (!present[i]) continue;
                    for (int j = i + 1; j < m; j++) {
                        if (present[j]) {
                            if (pairSeen[i, j])
                                return true; // rectangle found
                            pairSeen[i, j] = true;
                        }
                    }
                }
            }

            // Sparse row
            else {
                var row = rows[r];
                for (int i = 0; i < row.Count; i++) {
                    for (int j = i + 1; j < row.Count; j++) {
                        int c1 = row[i];
                        int c2 = row[j];
                        if (pairSeen[c1, c2])
                            return true; // rectangle found
                        pairSeen[c1, c2] = true;
                    }
                }
            }
        }
        return false;
    }

    static void Main() {
        int[,] mat = {
            {1, 0, 0, 1, 0},
            {0, 0, 1, 0, 1},
            {0, 0, 0, 1, 0},
            {1, 0, 1, 0, 1}
        };

        Console.WriteLine(ValidCorner(mat) ? "true" : "false");
    }
}
JavaScript
function ValidCorner(mat) {

    let n = mat.length;
    let m = mat[0].length;

    let rows = [];
    let totalOnes = 0;

    // collect columns with 1s
    for (let i = 0; i < n; i++) {
        let cols = [];
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 1) {
                cols.push(j);
                totalOnes++;
            }
        }
        rows.push(cols);
    }

    let threshold = Math.floor(Math.sqrt(totalOnes));

    // pairSeen[c1][c2] = whether any previous row had both c1 and c2
    let pairSeen = Array.from({ length: 205 }, () => Array(205).fill(false));

    // For dense rows: mark column presence
    let present = Array(m).fill(false);

    for (let r = 0; r < n; r++) {

        // Dense row
        if (rows[r].length >= threshold) {
            present.fill(false);
            for (let c of rows[r]) {
                present[c] = true;
            }

            // Check all column pairs directly
            for (let i = 0; i < m; i++) {
                if (!present[i]) continue;
                for (let j = i + 1; j < m; j++) {
                    if (present[j]) {
                        if (pairSeen[i][j])
                            return true; // rectangle found
                        pairSeen[i][j] = true;
                    }
                }
            }
        }

        // Sparse row
        else {
            let row = rows[r];
            for (let i = 0; i < row.length; i++) {
                for (let j = i + 1; j < row.length; j++) {
                    let c1 = row[i];
                    let c2 = row[j];
                    if (pairSeen[c1][c2])
                        return true; // rectangle found
                    pairSeen[c1][c2] = true;
                }
            }
        }
    }
    return false;
}

// Driver Code
let mat = [
    [1, 0, 0, 1, 0],
    [0, 0, 1, 0, 1],
    [0, 0, 0, 1, 0],
    [1, 0, 1, 0, 1]
];

console.log(ValidCorner(mat) ? "true" : "false");

Output
true

Time complexity: O(r * c + N√N + √N * c²), where N is the total number of 1s in the matrix and r and c are the number of rows and columns respectively. In the worst case (N ≈ r * c), this becomes O(r * c * √(r * c))
Auxiliary space: O(N + c²), for storing column indices of all 1’s in the matrix and for maintaining the column-pair tracking structure.

Comment