Open In App

Submatrix with corners as 1

Last Updated : 22 May, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

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.

[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){
    
    vector<vector<short>> rows;
    int N = 0;
    
    // Preprocess: Store columns with 1s for each row
    for (const auto& row : mat) {
        vector<short> cols;
        for (short c = 0; c < row.size(); ++c) {
            if (row[c]) cols.push_back(c);
        }
        rows.push_back(cols);
        N += cols.size();
    }

    int sqrtN = sqrt(N);
    unordered_set<int> pairs;

    for (int r = 0; r < rows.size(); ++r) {
        if (rows[r].size() >= sqrtN) {
            // Dense row: Check against all previous rows
            unordered_set<short> cols(rows[r].begin(), rows[r].end());
            for (int r2 = 0; r2 < r; ++r2) {
                int common = 0;
                for (short c : rows[r2]) {
                    if (cols.count(c)) common++;
                    if (common >= 2) return true; // Early exit
                }
            }
        } else {
            // Sparse row: Check column pairs
            for (int i = 0; i < rows[r].size(); ++i) {
                for (int j = i+1; j < rows[r].size(); ++j) {
                    int key = (rows[r][i] << 13) | rows[r][j];
                    if (pairs.count(key)) return true;
                    pairs.insert(key);
                }
            }
        }
    }
    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) {
        
        List<List<Short>> rows = new ArrayList<>();
        int N = 0;
        
        // Preprocess: Store columns with 1s for each row
        for (int[] row : mat) {
            List<Short> cols = new ArrayList<>();
            for (short c = 0; c < row.length; ++c) {
                if (row[c] == 1) cols.add(c);
            }
            rows.add(cols);
            N += cols.size();
        }

        int sqrtN = (int)Math.sqrt(N);
        Set<Integer> pairs = new HashSet<>();

        for (int r = 0; r < rows.size(); ++r) {
            if (rows.get(r).size() >= sqrtN) {
                // Dense row: Check against all previous rows
                Set<Short> cols = new HashSet<>(rows.get(r));
                for (int r2 = 0; r2 < r; ++r2) {
                    int common = 0;
                    for (short c : rows.get(r2)) {
                        if (cols.contains(c)) {
                            common++;
                            // Early exit
                            if (common >= 2) return true; 
                        }
                    }
                }
            } else {
                // Sparse row: Check column pairs
                List<Short> row = rows.get(r);
                for (int i = 0; i < row.size(); ++i) {
                    for (int j = i + 1; j < row.size(); ++j) {
                        int key = (row.get(i) << 13) | row.get(j);
                        if (pairs.contains(key)) return true;
                        pairs.add(key);
                    }
                }
            }
        }
        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):
    
    rows = []
    N = 0
    
    # Preprocess: Store columns with 1s for each row
    for row in mat:
        cols = []
        for c in range(len(row)):
            if row[c] == 1:
                cols.append(c)
        rows.append(cols)
        N += len(cols)

    sqrtN = int(math.sqrt(N))
    pairs = set()

    for r in range(len(rows)):
        if len(rows[r]) >= sqrtN:
            # Dense row: Check against all previous rows
            cols = set(rows[r])
            for r2 in range(r):
                common = 0
                for c in rows[r2]:
                    if c in cols:
                        common += 1
                        if common >= 2:
                            return True  # Early exit
        else:
            # Sparse row: Check column pairs
            row = rows[r]
            for i in range(len(row)):
                for j in range(i + 1, len(row)):
                    key = (row[i] << 13) | row[j]
                    if key in pairs:
                        return True
                    pairs.add(key)
    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]
    ]
    print("true" if ValidCorner(mat) else "false")
C#
using System;
using System.Collections.Generic;

class GfG{
    
    static bool ValidCorner(int[][] mat) {
    
        List<List<short>> rows = new List<List<short>>();
        int N = 0;
        
        // Preprocess: Store columns with 1s for each row
        foreach (var row in mat) {
            List<short> cols = new List<short>();
            for (short c = 0; c < row.Length; ++c) {
                if (row[c] == 1) cols.Add(c);
            }
            rows.Add(cols);
            N += cols.Count;
        }

        int sqrtN = (int)Math.Sqrt(N);
        HashSet<int> pairs = new HashSet<int>();

        for (int r = 0; r < rows.Count; ++r) {
            if (rows[r].Count >= sqrtN) {
                // Dense row: Check against all previous rows
                HashSet<short> cols = new HashSet<short>(rows[r]);
                for (int r2 = 0; r2 < r; ++r2) {
                    int common = 0;
                    foreach (short c in rows[r2]) {
                        if (cols.Contains(c)) {
                            common++;
                            if (common >= 2) return true; // Early exit
                        }
                    }
                }
            } else {
                // Sparse row: Check column pairs
                var row = rows[r];
                for (int i = 0; i < row.Count; ++i) {
                    for (int j = i + 1; j < row.Count; ++j) {
                        int key = (row[i] << 13) | row[j];
                        if (pairs.Contains(key)) return true;
                        pairs.Add(key);
                    }
                }
            }
        }
        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}
        };

        Console.WriteLine(ValidCorner(mat) ? "true" : "false");
    }
}
JavaScript
function ValidCorner(mat) {
    
    let rows = [];
    let N = 0;
    
    // Preprocess: Store columns with 1s for each row
    for (let row of mat) {
        let cols = [];
        for (let c = 0; c < row.length; c++) {
            if (row[c] === 1) cols.push(c);
        }
        rows.push(cols);
        N += cols.length;
    }

    let sqrtN = Math.floor(Math.sqrt(N));
    let pairs = new Set();

    for (let r = 0; r < rows.length; r++) {
        if (rows[r].length >= sqrtN) {
            // Dense row: Check against all previous rows
            let cols = new Set(rows[r]);
            for (let r2 = 0; r2 < r; r2++) {
                let common = 0;
                for (let c of rows[r2]) {
                    if (cols.has(c)) {
                        common++;
                        if (common >= 2) return true;  // Early exit
                    }
                }
            }
        } else {
            // Sparse row: Check column pairs
            let row = rows[r];
            for (let i = 0; i < row.length; i++) {
                for (let j = i + 1; j < row.length; j++) {
                    let key = (row[i] << 13) | row[j];
                    if (pairs.has(key)) return true;
                    pairs.add(key);
                }
            }
        }
    }
    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 + r * c * √N + N) — for preprocessing, dense row comparison, and sparse row column pair checks. In the worst case (N ≈ r*c), it becomes O(r * c* √(r * c)). where N is the number of 1's and r and c is number rows and columns.
Auxiliary space: O(N), for storing 1's column indices and column pairs, number of 1's.


Next Article

Similar Reads