题目的主要信息:

输出从1开始的自然数依次排列成的一个矩阵上三角形。

方法一:找规律

蛇形矩阵的每一行数字是有规律的,如下图所示: alt

  • 若第i行的第一个数字为j,则第i+1行的第一个数字为j+i;
  • 若每i行的第一个数字为j,则该行的第二个数字为i+(j+1),第三个数字为i+(j+2),以此类推。

具体做法:

#include<iostream>

using namespace std;

int main(int argc, char** argv)
{
    int n;
    while(cin>>n){
        int num=1;
        for(int i=1;i<=n;++i){//总共要输出n行
            cout<<num;//每一行的第一个数字
            int ans=num;
            for (int j=i+1;j<=n;++j){//每一行的输出
                ans+=j;
                cout<<' '<<ans;
            }
            num+=i;//更新num的值为下一行的输出
            cout<<endl;
        }
    }
}

复杂度分析:

  • 时间复杂度:O(n2)O(n^2),两个for循环。
  • 空间复杂度:O(1)O(1),只使用了常数空间。

方法二:

具体做法:

数字从小到大逐个填入矩阵中,填入的过程如下图所示: alt 从这个过程可以看到,每次从某一行的第一列开始,不断往右上角放入数字,当右上角不能再放入数字后就切到下一行继续。在矩阵往右上角移动很简单,假设当前位置为(i,j),则(i-1,j+1)就是(i,j)的右上角元素。

#include<iostream>
#include<vector>

using namespace std;

int matrix[100][100];

int main()
{
    int n=0;
    while(cin>>n){
        vector<vector<int>> m(n,vector<int>(n,0));
        int d=1;
        for(int i=0;i<n;i++){
            int row=i;//每次从每行的第一格开始
            int col=0;//从m[row][0]开始
            while(row>=0){//row<0时说明不能再往右上走了
                m[row][col]=d++;
                //向右上角移动
                row--;
                col++;
            }
        }
        for(int i=0;i<n;i++){//逐行输出
            for(int j=0;j<n-i;j++){//第i行输出的个数为n-i
                cout<<m[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n2)O(n^2),for循环嵌套了while循环。
  • 空间复杂度:O(1)O(1),只使用了常数空间。