SWE · Coding

Meta 矩阵连续数值路径:加1有向图与重构

求4邻接且下一格恰好大1的最长路径,利用值顺序构成DAG并返回坐标链。

题目重点:求4邻接且下一格恰好大1的最长路径,利用值顺序构成DAG并返回坐标链。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练4邻接、next=current+1,返回任意最长坐标path;值可重复,但相等格不连接。不是仅next>current的树路径,也不是要求包含1..N所有数。
  • 不采用不自洽的示例:如果矩阵缺8,就不能声称存在1..9连续链;是否全值唯一需按实际给定。

解题路线

  1. 每个合法边从值v到v+1,沿路径值严格上升,因此无环,即使矩阵里有重复值也成立。可按值降序处理动态规划。
  2. length[cell]=1+max(length[next]),next仅为4邻恰+1;没有合法后继为1。降序保证后继已计算,记录following用于最后重构。
  3. 遍历所有格找bestStart,不只从最小值或角落开始。值最小处可能孤立,真正长链从别处开始。
  4. 不要每格保存整条path再拼接,会有多次重复复制;仅长度与一个next,最后O(L)跟指针。
  5. 可用memo DFS把排序时间降为O(RC),但递归深度可能长;当前迭代排序基线免递归上限,并如实计排序成本。

手动走一遍

[[1,2,9],[4,3,8],[5,6,7]]可走1→2→3→4→5→6→7→8→9,长度9。[[1,3]]没有+1边,最长1,不能因为3更大就连。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def longest_consecutive_path(grid):
    """Four-neighbor next value exactly current+1, return coordinate path.

    Values need not be globally distinct; equal-valued neighbors are not edges.
    """
    if not grid or not grid[0]:return []
    rows,cols=len(grid),len(grid[0])
    if any(len(row)!=cols for row in grid):raise ValueError('rectangular grid')
    order=sorted(((r,c) for r in range(rows) for c in range(cols)),key=lambda p:grid[p[0]][p[1]],reverse=True)
    lengths={};following={};best=None
    for r,c in order:
        length=1;successor=None
        for dr,dc in ((-1,0),(1,0),(0,-1),(0,1)):
            rr,cc=r+dr,c+dc
            if 0<=rr<rows and 0<=cc<cols and grid[rr][cc]==grid[r][c]+1 and lengths[rr,cc]+1>length:
                length=lengths[rr,cc]+1;successor=(rr,cc)
        lengths[r,c]=length;following[r,c]=successor
        if best is None or length>lengths[best]:best=(r,c)
    path=[]
    while best is not None:path.append(best);best=following[best]
    return path

复杂度

O(N log N)排序+O(N)4邻DP,N=RC,空间O(N)、输出O(L)。Memo DFS可O(N)时间但需栈/缓存;两实现复杂度不能混写。

易错点与追问

容易失分的边界

  • 把大于条件当恰好+1,会输出跳号路径。
  • 只从最小值开始,漏掉其他最长起点。
  • 坏例缺值仍称全序连续,损害题意可信度。

继续深挖

  • 若允许next任意更大,仍是DAG但边与约束不同;仅改边条件即可保持降序DP。
  • 若next可以−1或+1,环出现,最长简单路径不能直接套同一递推。
✓已复制微信号!