LC 2573. 找出对应 LCP 矩阵的字符串

我最初想到的办法非常复杂,其实是去根据已有的条件尝试构建连通图

class Solution:
    def findTheString(self, lcp: List[List[int]]) -> str:
        n = len(lcp)
        # quick check and build graph
        grid = [[] * n for _ in range(n)]
        for i in range(n):
            if lcp[i][i] != (n - i):
                return ''
            for j in range(i + 1, n):
                if lcp[i][j] != lcp[j][i]:
                    return ''
                d = lcp[i][j]
                if d > (n - max(i, j)):
                    return ''
                if d > 0:
                    if (j + 1) < n and lcp[i + 1][j + 1] != (d - 1):
                        return ''
                    grid[i].append(j)
                    grid[j].append(i)

        # dfs and build connected graph.
        ts = [0] * n

        def dfs(x, now):
            if ts[x] != 0:
                return ts[x] == now
            ts[x] = now
            for y in grid[x]:
                if not dfs(y, now):
                    return False
            return True

        now = 1
        for i in range(n):
            if ts[i]: continue
            # too much connected graphs.
            if now > 26: return ''
            if not dfs(i, now):
                return ''
            now += 1

        ans = [''] * n
        for i in range(n):
            ans[i] = chr(ord('a') + ts[i] - 1)
        ans = ''.join(ans)

        # double check because we only looks for positive requirements.
        # we need to take care of negative requirements.
        for i in range(n):
            for j in range(i + 1, n):
                if lcp[i][j] == 0 and ans[i] == ans[j]:
                    return ''

        return ans

题解中的解法思路也差不多,但是构建方式不同,所以代码异常地简单:

class Solution:
    def findTheString(self, lcp: List[List[int]]) -> str:
        n = len(lcp)
        ans = [''] * n

        # construct loosely answer.
        import string
        i = 0
        for c in string.ascii_lowercase:
            while i < n and ans[i] != '': i += 1
            if i == n: break
            for j in range(i, n):
                if lcp[i][j]: ans[j] = c
        if '' in ans: return ''

        for i in reversed(range(n)):
            for j in reversed(range(i, n)):
                if lcp[i][j] != lcp[j][i]: return ''
                value = 0
                if ans[i] == ans[j]:
                    value = lcp[i + 1][j + 1] if (j + 1) < n else 0
                    value += 1
                if lcp[i][j] != value:
                    return ''

        return ''.join(ans)