问题:小U得到了一个数字n,他的任务是构造一个特定数组。这个数组的构造规则是:对于每个i从1到n,将数字n到i逆序拼接,直到i等于n为止。最终,输出这个拼接后的数组。
例如,当n等于3时,拼接后的数组是 [3, 2, 1, 3, 2, 3]。
测试样例
样例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]
解题思路
- 初始化数组:我们需要一个数组来存储最终的结果。
- 循环构造数组:对于每个
i从1到n,我们需要将n到i的数字逆序添加到数组中。 - 返回结果:最后返回构造好的数组。
代码实现:`` import java.util.ArrayList; import java.util.List;
public class Main { public static int[] solution(int n) { // 使用 List 来动态添加元素 List resultList = new ArrayList<>();
// 外层循环,从 1 到 n
for (int i = 1; i <= n; i++) {
// 内层循环,从 n 到 i,逆序添加到 resultList
for (int j = n; j >= i; j--) {
// 添加元素到 resultList
resultList.add(j);
}
}
// 将 List 转换为数组
int[] resultArray = new int[resultList.size()];
for (int k = 0; k < resultList.size(); k++) {
resultArray[k] = resultList.get(k);
}
return resultArray;
}
public static void main(String[] args) {
// 注意:Arrays 类需要导入 java.util.Arrays
System.out.println(java.util.Arrays.equals(solution(3), new int[]{3, 2, 1, 3, 2, 3}));
System.out.println(java.util.Arrays.equals(solution(4), new int[]{4, 3, 2, 1, 4, 3, 2, 4, 3, 4}));
System.out.println(java.util.Arrays.equals(solution(5), new int[]{5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5}));
}
}
关键步骤解释
- 使用
List动态添加元素:由于数组的长度不确定,我们使用List来动态添加元素。 - 外层循环:从
1到n,表示每次需要逆序添加的数字范围。 - 内层循环:从
n到i,逆序添加到resultList。 - 转换为数组:最后将
List转换为数组并返回。
注意
- 导入
Arrays类:在main方法中,你需要导入java.util.Arrays类,或者在调用Arrays.equals时使用全限定名java.util.Arrays.equals。
还可以优化
1. 减少不必要的循环
当前代码的时间复杂度是 O(n^2),因为外层循环和内层循环都遍历了 n 次。我们可以通过减少内层循环的次数来优化时间复杂度。
2. 使用数组而不是列表
虽然 List 提供了动态添加元素的便利,但在转换为数组时需要额外的遍历。我们可以直接使用数组来存储结果,这样可以减少一次遍历。
3. 预先计算数组大小
我们可以预先计算出结果数组的大小,这样可以避免动态调整数组大小的开销。
关键步骤解释
- 预先计算数组大小:通过一个循环计算出结果数组的大小,这样可以避免动态调整数组大小的开销。
- 直接使用数组:使用数组来存储结果,避免将
List转换为数组的开销。 - 减少内层循环次数:内层循环的次数已经是最优的,无法进一步减少。
时间复杂度分析
- 预先计算数组大小:时间复杂度为
O(n)。 - 外层循环:时间复杂度为
O(n)。 - 内层循环:总的时间复杂度为
O(n),因为内层循环的总次数是n + (n-1) + (n-2) + ... + 1,即n(n+1)/2,仍然是O(n^2),但由于我们预先计算了数组大小,实际运行时间会减少。
通过这些优化,代码的时间复杂度仍然是 O(n^2),但在实际运行中会有显著的性能提升。