Largest Square of Ones

medium Matrix (2D arrays)

Problem

The grid has only 0 and 1. Find the biggest square made only of 1s. Print the length of its side (0 if there is no 1). Input: rows and columns, then the grid.

Constraints

  • 1 <= r, c <= 100
  • grid values are 0 or 1

Examples

Input

4 5
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

Output

2

Solutions

Best approachTime O(r * c)Space O(r * c)

A square with its corner at (i, j) can only be as big as the smallest of its three neighbours' squares plus one. One pass fills the table, so it is O(r * c).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Biggest square of ones.
 * Input   : r and c, then the grid.
 * Output  : Side length.
 * Approach: Dynamic programming.
 * Time    : O(r * c)
 * Space   : O(r * c)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static long solve(int[][] m) {
        // Step 1: side[i][j] is the side of the biggest square of ones that has its bottom-right corner at (i, j).
        int rows = m.length;
        int columns = m[0].length;
        int[][] side = new int[rows][columns];
        int best = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (m[i][j] == 0) {
                    continue;
                }
                // Step 2: On the border the square has side 1. Inside, it is 1 plus the smallest of the up, left and up-left squares.
                if (i == 0 || j == 0) {
                    side[i][j] = 1;
                } else {
                    side[i][j] = 1 + Math.min(side[i - 1][j - 1], Math.min(side[i - 1][j], side[i][j - 1]));
                }
                best = Math.max(best, side[i][j]);
            }
        }
        return best;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int rows = scanner.nextInt();
        int cols = scanner.nextInt();
        int[][] m = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                m[i][j] = scanner.nextInt();
            }
        }
        System.out.println(solve(m));
    }
}
Hints (2)
  1. What is the answer on the first row?
  2. Why the minimum of three neighbours?