构造特定数组问题

111 阅读4分钟

学习笔记:构造特定数组问题解析与解题心得

一、题目描述

给定一个正整数 nn,需要按照以下规则构造一个数组:

  1. 对于每个 ii 从 1 到 nn,将数字从 nn 到 ii 的序列逆序拼接到数组中。
  2. 最终返回拼接后的数组。

测试样例:

  • 样例1:

    输入:n = 3
    输出:[3, 2, 1, 3, 2, 3]
    
  • 样例2:

    输入:n = 4
    输出:[4, 3, 2, 1, 4, 3, 2, 4, 3, 4]
    
  • 样例3:

    输入:n = 5
    输出:[5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5]
    

二、思路分析

1. 问题分析

  • 每次需要将从 nn 到 ii 的数字逆序拼接到数组中。
  • 每个 ii 的拼接规则是固定的,从大到小排列。
  • 最终数组长度为 n+(n−1)+(n−2)+...+1=n×(n+1)/2n + (n-1) + (n-2) + ... + 1 = n \times (n + 1) / 2。

2. 逐步实现

外层循环:

遍历 ii 从 1 到 nn,对于每个 ii:

  • 将从 nn 到 ii 的数字拼接到结果数组。
内层循环:

从 nn 递减到 ii,逐一将数字加入结果数组。


三、代码实现

代码:

#include <vector>

std::vector<int> solution(int n) {
    std::vector<int> result; // 存储最终的结果数组
    for (int i = 1; i <= n; ++i) { // 外层循环
        for (int j = n; j >= i; --j) { // 内层逆序拼接
            result.push_back(j);
        }
    }
    return result;
}

代码详解:

  1. 初始化结果数组:

    std::vector<int> result;
    
    • 用于存储最终的拼接结果。
  2. 外层循环:

    for (int i = 1; i <= n; ++i) {
    
    • 从 i=1i = 1 开始遍历到 i=ni = n,每次处理一个逆序序列。
  3. 内层循环:

    for (int j = n; j >= i; --j) {
        result.push_back(j);
    }
    
    • 从 nn 递减到当前的 ii,将所有数字依次加入结果数组。
  4. 返回结果:

    return result;
    
    • 返回拼接完成的数组。

四、测试样例分析

样例1:

输入:n = 3
输出:[3, 2, 1, 3, 2, 3]
  • 循环过程:

    • i=1i = 1:拼接 [3, 2, 1]
    • i=2i = 2:拼接 [3, 2]
    • i=3i = 3:拼接 [3]
  • 最终数组: [3, 2, 1, 3, 2, 3]


样例2:

输入:n = 4
输出:[4, 3, 2, 1, 4, 3, 2, 4, 3, 4]
  • 循环过程:

    • i=1i = 1:拼接 [4, 3, 2, 1]
    • i=2i = 2:拼接 [4, 3, 2]
    • i=3i = 3:拼接 [4, 3]
    • i=4i = 4:拼接 [4]
  • 最终数组: [4, 3, 2, 1, 4, 3, 2, 4, 3, 4]


样例3:

输入:n = 5
输出:[5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5]
  • 循环过程:

    • i=1i = 1:拼接 [5, 4, 3, 2, 1]
    • i=2i = 2:拼接 [5, 4, 3, 2]
    • i=3i = 3:拼接 [5, 4, 3]
    • i=4i = 4:拼接 [5, 4]
    • i=5i = 5:拼接 [5]
  • 最终数组: [5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5]


五、复杂度分析

1. 时间复杂度:

外层循环运行 nn 次,内层循环每次执行 n−i+1n-i+1 次,执行次数总和为:

T=n+(n−1)+(n−2)+⋯+1=n×(n+1)2T = n + (n-1) + (n-2) + \dots + 1 = \frac{n \times (n+1)}{2}

因此,时间复杂度为 O(n2)O(n^2)

2. 空间复杂度:

结果数组的长度为:

L=n×(n+1)2L = \frac{n \times (n+1)}{2}

因此,空间复杂度为 O(n2)O(n^2)


六、学习心得

1. 问题拆解

  • 逐步分析构造规则,找到规律后再逐步实现。
  • 通过将外层和内层循环明确分离,避免逻辑混乱。

2. 循环嵌套的优化思路

  • 充分利用数学公式计算循环次数,避免重复操作。
  • 在复杂嵌套循环中,优先考虑时间复杂度是否满足题目要求。

3. 代码优化

  • 避免冗余操作: 直接拼接数字,无需重复计算。
  • 使用适当数据结构: 选择动态数组(如 std::vector)以高效存储和扩展数据。

七、学习建议

  1. 从简单问题入手:

    • 先解决基本的循环嵌套问题,逐步过渡到复杂问题。
  2. 记录总结:

    • 在完成每道题目后,记录解题思路和复杂度分析,形成知识体系。
  3. 优化代码:

    • 学会从算法和代码层面优化,提高代码的执行效率和可读性。
  4. 多做题巩固:

    • 利用豆包MarsCode AI刷题功能,坚持练习类似问题。

八、工具运用

  • 豆包MarsCode AI刷题功能:

    • 提供即时反馈,帮助理解问题,优化算法。
  • 学习资源:

    • 使用在线平台学习算法基础知识,结合题目练习应用。
  • 社区交流:

    • 通过社区讨论分享解题经验,获得不同的解题思路。

九、结语

通过本题,我们熟悉了多层嵌套循环的设计思路,掌握了数组动态构造的技巧。算法设计需要注重时间和空间复杂度的权衡,在实践中不断优化代码实现,提升解决问题的能力。希望这篇笔记对你的学习有所帮助,让我们共同进步!