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

31 阅读3分钟

问题描述

小U得到了一个数字n,他的任务是构造一个特定数组。这个数组的构造规则是:对于每个i从1到n,将数字n到i逆序拼接,直到i等于n为止。最终,输出这个拼接后的数组。 例如,当n等于3时,拼接后的数组是 [3, 2, 1, 3, 2, 3]

问题分析

题目要求构造一个特定的数组,其构造规则是:对于每个从1到n的数字,将这个数字到n的范围倒序拼接,直到n为止,输出最终的拼接数组。通过题目示例可以观察到模式:

  • 当 n=3:输出数组为 [3,2,1,3,2,3]。
  • 当 n=4:输出数组为 [4,3,2,1,4,3,2,4,3,4]。

上述模式中,可以发现:

  1. 每次迭代,数组拼接的子数组范围从当前数字开始到 n 倒序排列。
  2. 随着 i 从 1 到 n 递增,倒序拼接的数组会依次减少一位。
  3. 整体构造规则符合嵌套式循环结构。

实现思路

为了解决这个问题,可以采用以下实现步骤:

  1. 定义一个用于存储结果的数组 number,初始为空。
  2. 外层循环从 i=1 遍历到 n,代表起始数字。
  3. 内层循环从 j=n 遍历到 i,将倒序范围内的数字依次插入到结果数组。
  4. 每次内层循环结束后,数组逐步累积构造的子序列。
  5. 最后,返回结果数组。

这种构造方法有效利用了嵌套循环和向量数据结构的特性。


数据结构

  1. 向量(vector

    • 本题使用C++标准模板库(STL)中的vector作为主要的数据结构。
    • vector提供了动态大小调整的能力,可以方便地在末尾添加元素。
    • 内部实现基于动态数组,因此支持快速的索引和尾部插入操作(摊销时间复杂度为 O(1))。
  2. 整数变量

    • 用于控制循环范围的变量 i 和 j,它们的作用是精确确定当前子数组的起始和结束位置。

注意点

  1. 嵌套循环的边界条件

    • 外层循环控制从 i=1 到 n,而内层循环从 j=n 递减到 i。边界条件需要仔细设置,确保不会越界或漏掉任何范围。
  2. 向量的动态扩展

    • 在C++中,vector的动态扩展是自动完成的,但在高频插入操作时,可能会触发扩容,这会带来一定的性能开销。因此,理解其内部机制有助于优化程序(例如在构造前预先分配内存)。

代码实现

#include <iostream>
#include <vector>

using namespace std;

// 函数实现:构造特定数组
vector<int> solution(int n) {
  vector<int> number; // 用于存储结果的动态数组
  // 外层循环:从1到n
  for (int i = 1; i <= n; ++i) {
    // 内层循环:从n倒序到i
    for (int j = n; j >= i; --j) {
      number.push_back(j); // 插入结果数组
    }
  }
  return number; // 返回最终数组
}

// 主函数:测试样例
int main() {
  // 测试用例1
  vector<int> result1 = solution(3);
  cout << (result1 == vector<int>{3, 2, 1, 3, 2, 3}) << endl;

  // 测试用例2
  vector<int> result2 = solution(4);
  cout << (result2 == vector<int>{4, 3, 2, 1, 4, 3, 2, 4, 3, 4}) << endl;

  // 测试用例3
  vector<int> result3 = solution(5);
  cout << (result3 == vector<int>{5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5})
       << endl;

  return 0;
}

总结

通过本问题的实现,可以学习到如何构造嵌套循环以满足复杂的数组构造需求,同时巩固对C++中vector数据结构的动态管理能力。算法的设计和优化主要围绕时间复杂度和空间复杂度展开。虽然本题属于入门级,但其背后的嵌套循环和边界控制逻辑是解决更多复杂问题的基础。