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

32 阅读3分钟

我们最后要返回一个拼接后的数组,那么我们首先要定义一个数组,要定义数组就必须要知道数组的大小。所以自然引出第一个问题:数组大小是多少呢?

可以观察一下样例。n=3时,输出为[3,2,1,3,2,3]。根据题意,i首先为1,将数字3到1逆序加入数组,即3,2,1,一共3个;然后i为2,将数字3到2逆序加入数组,即3,2,一共2个;接着i为3,将数字3加入数组,一共1个。所以算出数组的大小为3+2+1=6。推广到一般的情况,i首先为1,将数字n到1逆序加入数组,即n,n-1,n-2...2,1,一共n个;然后i为2,将数字n到2逆序加入数组,即n,n-1,n-2...2,一共n-1个;······最后i为n,将数字n加入数组,一共1个。我们可以算出数组的大小为n+(n-1)+(n-2)+...+2+1=(1+n)*n/2。所以我们就得到了数组的大小:

int size = (1 + n) * n / 2;

接下来我们就要按照题意,根据给出的n将数字逐个加入到数组中。怎么做呢?乍一看样例,如果n比较小,比如上面提到的n=3时的情况,最后的结果看起来好像比较短。但是n如果比较大,比如n=100,结果岂不是很长很长?我们可以先简化问题,先不急着想怎么把数加到数组中,可以先想想怎么样逐个枚举每一个数。

当我们回到题目,就会发现要做到这一点是比较简单的。从题目中我们就不难看到枚举的范围:枚举每一个i从1到n,对于每一个i,再倒序枚举数字n到i。这是一个典型的循环枚举问题,外层循环为i从1到n,内层循环为j从n到i。

解决了如何逐个枚举每一个数的问题之后,我们就可以想想怎么样把数加到数组里。通常我们在循环里使用数组时,数组下标会和i、j有关系。但在这道题里面,我们会发现无法用循环参数i、j来表示数组下标,那怎么办呢?其实,可以引入一个辅助计数器cnt,让cnt从0开始计数,在内层循环每遍历一个数j,就能将这个数j加入到当前数组下标cnt对应的位置,然后cnt自增,继续下一轮循环:

result[cnt] = j; cnt++;

循环结束,我们也就完成了将数字加入到数组的工作,返回数组即可。

总结一下,这是一道典型的模拟+循环枚举的题目。完整代码如下:

public static int[] solution(int n) {
        // write code here
        int size = (1 + n) * n / 2;
        int[] result = new int[size];
        int cnt = 0;

        for (int i = 1; i <= n; i++) {
            for (int j = n; j >= i; j--) {
                result[cnt] = j;
                cnt++;
            }
        }
        return result;
}