问题解析:
小U面临的任务是生成一个特定规则的数组。这个数组的生成规则是:从数字 n 开始,逐渐逆序拼接到 1,依次构造多个部分数组,然后将它们按照顺序拼接在一起。最终,我们需要输出这个完整的数组。具体来说,对于输入的 n,结果数组的长度为 n×(n+1)2\frac{n \times (n + 1)}{2},即随着 n 的增大,数组的长度呈现二次增长。因此,这道题的关键在于如何高效地生成这些部分数组并完成拼接。
例如,当 n = 3 时,生成的结果数组为 [3, 2, 1, 3, 2, 3]。可以看出,它由以下部分数组构成:
- 第1部分:从
3到1,结果为[3, 2, 1]; - 第2部分:从
3到2,结果为[3, 2]; - 第3部分:从
3到3,结果为[3]。
将这些部分数组按顺序拼接在一起,就得到最终结果。
解题思路:
-
构造部分数组:
每次从n开始,逆序生成到当前的i(其中 1≤i≤n1 \leq i \leq n)。- 第一次生成从
n到1的完整逆序数组。 - 第二次生成从
n到2的部分数组。 - 依此类推,直到第
n次,仅包含n自身。
这些部分数组彼此独立,但拼接后的顺序影响最终结果。
- 第一次生成从
-
拼接数组:
使用一个结果数组存储每次生成的部分数组。通过extend方法将部分数组高效地拼接到结果数组中,避免逐个元素插入带来的额外开销。 -
优化拼接逻辑:
在每次生成部分数组时,通过构造列表的方式(如使用range)减少不必要的循环,直接生成需要的逆序序列。 -
代码实现:
将上述思路转化为代码,并保证其可读性和高效性。
代码实现:
def solution(n: int) -> list:
# 初始化结果数组
result = []
# 逐步生成从 n 到 i 的部分数组
for i in range(1, n + 1):
# 生成从 n 到 i 的逆序部分数组
sub_array = list(range(n, i - 1, -1))
# 将部分数组拼接到结果数组
result.extend(sub_array)
return result
测试代码:
if __name__ == '__main__':
print(solution(3) == [3, 2, 1, 3, 2, 3]) # 测试用例1
print(solution(4) == [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]) # 测试用例2
print(solution(5) == [5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5]) # 测试用例3
复杂度分析:
-
时间复杂度:
- 每次生成部分数组的时间复杂度为 O(n−i+1)O(n - i + 1)。
- 总体复杂度为 O(n+(n−1)+(n−2)+...+1)=O(n2)O(n + (n-1) + (n-2) + ... + 1) = O(n^2) 因此,时间复杂度为 O(n2)O(n^2)。
-
空间复杂度:
- 结果数组需要存储所有拼接后的元素,长度为 n×(n+1)2\frac{n \times (n + 1)}{2}。
- 因此,空间复杂度为 O(n2)O(n^2)。
解题思考:
-
解决核心问题:
这道题的难点在于生成部分数组和拼接的逻辑。通过直接使用range函数,简化了部分数组的生成过程,同时利用extend方法高效地拼接结果数组。 -
问题优化方向:
- 对于生成完整数组的场景,由于需要存储所有元素,空间复杂度很难进一步优化。
- 如果问题变为仅查询某个特定位置的值(例如索引
k对应的元素值),可以直接计算所在的部分数组并定位值,从而避免生成整个结果数组。
-
问题的拓展思路:
- 如果数组规模变得极大(例如 n>106n > 10^6),可以通过生成器函数(如
yield)动态生成部分数组,减少内存占用。 - 问题可以进一步延伸到不同的拼接规则,例如按升序或间隔跳跃生成部分数组。
- 如果数组规模变得极大(例如 n>106n > 10^6),可以通过生成器函数(如