SWE · Coding

Meta 矩阵对角线输出:每条同方向而非Zigzag

按对角线分组,每条从上到下打印,明确行列坐标与反对角线定义。

题目重点:按对角线分组,每条从上到下打印,明确行列坐标与反对角线定义。

题意与假设

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

  • 训练选择反对角线r+c固定,按r+c从小到大,每条r递增(从上到下);返回每条list。题目未给完整坐标约定,若要求主对角线r−c则需调整。
  • 不同于每隔一条反向的zigzag,不能看到diagonal就默认交替方向。
  • 另一种练习合同为zigzag:偶数r+c反向、奇数正向。先给小矩阵预期结果确认方向。

解题路线

  1. 对total=0..R+C−2,合法row下界max(0,total−C+1)、上界min(R−1,total),column=total−row,按row升序收集。
  2. 上下界来自0≤col<C与0≤row<R交集,支持长方形无需转置。每格恰好归一个total,不重复不遗漏。
  3. 同方向规则在所有total保持,不根据奇偶reverse。输出扁平还是每条一行是格式层,核心坐标次序不变。
  4. 如果从左上向右下主对角线,改用col−row常量和起点集合;必须给小矩阵预期输出来消除语言含混。
  5. diagonal_zigzag复用同向分组,对偶数total的整条结果逆转后拼接。每元素仍恰被处理一次,奇偶方向约定必须先对齐。

手动走一遍

[[1,2,3],[4,5,6]]反对角线同方向输出[1]、[2,4]、[3,5]、[6];zigzag会反转某些条,不能用它替代。 同一矩阵zigzag版本为[1,2,4,5,3,6],total2的[3,5]反向成[5,3]。

Python 参考实现

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

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

def diagonal_rows(matrix):
    """Training anti-diagonals row+col constant; each diagonal top-to-bottom.

    Return per-diagonal lists, not alternating zigzag or main diagonals.
    """
    if not matrix or not matrix[0]:return []
    rows,cols=len(matrix),len(matrix[0])
    if any(len(row)!=cols for row in matrix):raise ValueError('ragged matrix')
    result=[]
    for total in range(rows+cols-1):
        result.append([matrix[row][total-row] for row in range(max(0,total-cols+1),min(rows-1,total)+1)])
    return result


def diagonal_zigzag(matrix):
    """Standard anti-diagonals, alternate; even sum reversed, flat output."""
    result=[]
    for total,values in enumerate(diagonal_rows(matrix)):
        result.extend(reversed(values) if total%2==0 else values)
    return result

复杂度

O(RC)元素工作加O(R+C)条数,总O(RC)非空矩阵,输出O(RC),不含输出的索引状态O(1)。不用构造sort全部坐标,独立测试可排序(r+c,r)坐标对照。 zigzag构造分组和扁平输出,峰值O(RC),不能把这份实现说成O(1)辅助空间。

易错点与追问

容易失分的边界

  • 把Zigzag熟题顺序直接照搬。
  • 正方形专用上界导致矩形越界或漏右侧。

继续深挖

  • 输入是各行不同长度的ragged list时,当前矩形公式不适用,可按r+c分桶但改变空间。
  • 流式输出一条一条可用generator,峰值空间按一条最大长度。
✓已复制微信号!