Leetcode 1139: The largest square with a boundary of 1 (super detailed solution!!!)

Keywords: github

Give you a two-dimensional grid consisting of a number of zeros and ones. Find out the largest square sub-grid whose boundaries are all 1, and return the number of elements in the sub-grid. If it does not exist, return 0.

Example 1:

Input: grid = [[1,1,1],[1,0,1],[1,1,1]]
Output: 9

Example 2:

Input: grid = [[1,1,0,0]]
Output: 1 

Tips:

  • 1 <= grid.length <= 100
  • 1 <= grid[0].length <= 100
  • grid[i][j] is 0 or 1

Thoughts on Problem Solving

Firstly, it is not difficult to think of the violence method. Assuming that given grid length is C and height is r, we traverse the value K in the interval [0,min(r,c)] from large to small. We take this K as the width of the square, and then traverse every point of the grid, using it as the upper left corner of the square. Let's check if the square with K edge is legal. If it is legal, then it's the largest square. Just return to k**2.

class Solution:
    def largest1BorderedSquare(self, grid: List[List[int]]) -> int:
        r, c = len(grid), len(grid[0])
        def check(x1, y1, x2, y2):
            for x in range(x1, x2):
                if grid[x][y1] != 1 or grid[x][y2-1] != 1:
                    return False
            for y in range(y1, y2):
                if grid[x1][y] != 1 or grid[x2-1][y] != 1:
                    return False
            return True
             
        for k in range(min(r, c), 0, -1):
            for x1 in range(r):
                if x1 + k > r:
                    break
                for y1 in range(c):
                    x2, y2 = x1 + k, y1 + k
                    if y2 > c:
                        break
                    if check(x1, y1, x2, y2):
                        return k ** 2
        return 0

The time complexity of this algorithm is O(n^4) level, but after we submit it, we find that it can also pass.

Another O(n^3) level approach to this problem is also very easy to think of, that is, how many consecutive 1 are stored on the top and left side of each point through two matrices, so that when we check, we can complete the operation as long as O(1) time, assuming that the point we traverse is (x1,y1), and the edge length at this time is K. Then we just need to check the minimum values of the four points (x1,y1), (x1+k,y1), (x1,y1+k), (x1+k,y1+k) and compare whether they are larger than or equal to K. If so, K is what we want, otherwise continue to find.

class Solution:
    def largest1BorderedSquare(self, grid: List[List[int]]) -> int:
        r, c = len(grid), len(grid[0])
        h, v = [a[:] for a in grid], [a[:] for a in grid]
        for i in range(r):
            for j in range(c):
                if grid[i][j]:
                    if i:
                        v[i][j] = v[i-1][j] + 1
                    if j:
                        h[i][j] = h[i][j-1] + 1

        for k in range(min(r, c), 0, -1):
            for i in range(r - k + 1):
                for j in range(c - k + 1):
                    if min(v[i + k - 1][j], v[i + k - 1][j + k - 1], h[i][j + k - 1], h[i + k - 1][j + k - 1]) >= k:
                        return k**2
        return 0

In this way, the time complexity of our algorithm is O(n^3). We can also find the width K of the square from small to large. We first traverse the grid and take the minimum values of h[i][j] and v[i][j] as K. Then we judge whether it is legal to use (i,j) as a square whose width is k at the lower right corner. If it is not legal, we will reduce K and continue searching. Otherwise, we will record K at this time and judge the next point until all points have traversed to get the maximum value of K.

class Solution:
    def largest1BorderedSquare(self, grid: List[List[int]]) -> int:
        r, c = len(grid), len(grid[0])
        h, v = [a[:] for a in grid], [a[:] for a in grid]
        for i in range(r):
            for j in range(c):
                if grid[i][j]:
                    if i:
                        v[i][j] = v[i-1][j] + 1
                    if j:
                        h[i][j] = h[i][j-1] + 1

        res = 0
        for i in range(r):
            for j in range(c):
                if grid[i][j]:
                    s = min(h[i][j], v[i][j])
                    while s > res:
                        if v[i][j - s + 1] >= s and h[i - s + 1][j] >= s:
                            res = max(res, s)
                            break
                        s -= 1
        return res**2

The time complexity of the above algorithm is O(n^3), but the actual test results are the best.

reference:

https://www.geeksforgeeks.org/given-matrix-o-x-find-largest-subsquare-surrounded-x/

I added other language versions of the problem to my GitHub Leetcode

If there are any questions, I hope you can point out!!!

Posted by ironside82 on Mon, 29 Jul 2019 05:09:58 -0700