Leetcode 3529. Count Cells in Overlapping Horizontal and Vertical Substrings

1. 解题思路

这一题核心思路其实就是取出横向和纵向组成的两个长字符串,然后从中找出其中全部可以被pattern包括的位置,然后分别找出对应的节点的位置,最后将横向的结果和纵向的结果取一个交集即可。

这里,坐标的转换以及字符串的获取都是简单的,唯一的问题就在于如何在一个长字符串当中找出所有可以被pattern覆盖的位置,而这个就是一个典型的z算法的问题了,这里就不过多展开了,有兴趣的读者可以自行网上检索一下,我自己也写了一篇博客《经典算法:Z算法(z algorithm)》来作为备忘。

2. 代码实现

给出python代码实现如下:

def z_algorithm(s):
    n = len(s)
    z = [0 for _ in range(n)]
    l, r = -1, -1
    for i in range(1, n):
        if i > r:
            l, r = i, i
            while r < n and s[r-l] == s[r]:
                r += 1
            z[i] = r-l
            r -= 1
        else:
            k = i - l
            if z[k] < r - i + 1:
                z[i] = z[k]
            else:
                l = i
                while r < n and s[r-l] == s[r]:
                    r += 1
                z[i] = r-l
                r -= 1
    z[0] = n
    return z

class Solution:
    def countCells(self, grid: List[List[str]], pattern: str) -> int:
        n, m = len(grid), len(grid[0])
        l = len(pattern)
        
        s1 = set()
        horizontal = "".join([grid[i][j] for i in range(n) for j in range(m)])
        z = z_algorithm(pattern + horizontal)[l:]
        valid = 0
        for i, c in enumerate(z):
            row, col = i // m, i % m
            if c >= l:
                valid = i + l
            if i < valid:
                s1.add((row, col))

        vertical = "".join([grid[i][j] for j in range(m) for i in range(n)])
        z = z_algorithm(pattern + vertical)[l:]
        valid = 0
        s2 = set()
        for i, c in enumerate(z):
            row, col = i % n, i // n
            if c >= l:
                valid = i + l
            if i < valid:
                s2.add((row, col))

        return len(s1 & s2)

提交代码评测得到:耗时699ms,占用内存64.3MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值