13.构造特定数组的逆序拼接 | 豆包MarsCode AI刷题

2 阅读3分钟

问题背景

小U需要构造一个数组,满足一定的规则:

  • 给定一个正整数 (n),需要从 (n) 到 (1) 按逆序拼接数组。
  • 在完成一次逆序拼接后,继续去掉序列最右的数字,直到只剩下一个数字为止。
  • 最终的输出是多个拼接后的部分按顺序依次追加的数组。

示例分析

我们通过示例来逐步解析题意:

示例 1

  • 输入:(n = 3)
  • 拼接过程:
    1. 第一步,从 (3) 到 (1):[3, 2, 1]
    2. 第二步,从 (3) 到 (2):[3, 2]
    3. 第三步,从 (3) 到 (3):[3]
  • 输出:最终数组是 [3, 2, 1, 3, 2, 3]

示例 2

  • 输入:(n = 4)
  • 拼接过程:
    1. 第一步,从 (4) 到 (1):[4, 3, 2, 1]
    2. 第二步,从 (4) 到 (2):[4, 3, 2]
    3. 第三步,从 (4) 到 (3):[4, 3]
    4. 第四步,从 (4) 到 (4):[4]
  • 输出:最终数组是 [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]

题目抽象

对任意 (n):

  1. 对于每个 (i) 从 1 到 (n):将 ([n, n-1, \dots, i]) 拼接至结果数组。
  2. 每次递减 (i),以保留一个逐步缩减的递归式构造。
  3. 最终返回一个完整拼接的数组。

算法核心可以总结为:双重嵌套循环 + 动态数组拼接


解题思路

  1. 确定主循环逻辑:

    • 反向构造是从 (n) 到 (i),因此我们需要在外层对 (i) 从 (1) 遍历到 (n)。
    • 内层则是简单构造从 (n) 到 (i) 的递减序列。
  2. 模拟拼接过程:

    • 可以使用 Python 中的列表 (list),每次将一段生成的数组延展至最终结果。
  3. 算法复杂度分析:

    • 外层循环执行 (n) 次,内层每次生成的序列长度为 (n, n-1, \dots, 1)。
    • 时间复杂度:(O(n^2))。
    • 空间复杂度:结果数组占用 (O(n^2)) 的额外空间。

图解拼接过程

以 (n = 4) 为例,构造如下:

  1. 初始时 (i = 1):结果为 [4, 3, 2, 1] 阶段1转存失败,建议直接上传图片文件

  2. 第二步 (i = 2):拼接 [4, 3, 2] 阶段2转存失败,建议直接上传图片文件

  3. 第三步 (i = 3):拼接 [4, 3] 阶段3转存失败,建议直接上传图片文件

  4. 第四步 (i = 4):拼接 [4] 阶段4转存失败,建议直接上传图片文件

最终拼接完成,结果为 [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]。


代码实现

# 定义构造数组的函数
def solution(n):
    result = []  # 存储最终结果
    for i in range(1, n + 1):
        # 拼接从 n 到 i 的部分数组
        result.extend(range(n, i - 1, -1))
    return result

# 测试样例
if __name__ == "__main__":
    n1 = 3
    print(solution(n1))  # 输出:[3, 2, 1, 3, 2, 3]

    n2 = 4
    print(solution(n2))  # 输出:[4, 3, 2, 1, 4, 3, 2, 4, 3, 4]

代码详解

  1. result = []:
    • 定义一个空列表,存储最终构造的数组。
  2. for i in range(1, n + 1)::
    • 从 (i = 1) 遍历到 (n),逐步构造拼接段。
  3. range(n, i - 1, -1):
    • 使用 range 函数生成从 (n) 到 (i) 的递减序列。
  4. result.extend(...):
    • 将每次生成的序列追加到结果数组。
  5. 返回拼接完成的结果数组。

思考与优化

优化思路

目前算法的主要瓶颈在于:

  1. 每次 range 生成新序列,存在重复创建的开销。
  2. 多次拼接操作可能导致空间重新分配。

可以进一步优化:

  • **提前生成完整序列表:**使用倒序直接操作。
  • **合并数组拼接逻辑:**减少 Python 内部动态分配的次数。

替代方法

采用列表推导式优化拼接:

def construct_array_optimized(n):
    return [x for i in range(1, n + 1) for x in range(n, i - 1, -1)]

通过嵌套的列表推导式,生成最终数组,效率更高。