Leetcode 059 螺旋矩阵2 python C++ Java

题目:

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3
输出:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

算法过程:

按照填充的数学规律,把这个方阵填完。可以发现这一定是一个正方形的矩阵,而且横着向右填完一行后,下一次横着向右填的那一行的行数等于上一次填的行数+1,其他运动有类似的结论,所以在代码中出现了up += 1的代码。那确定了填的行数,从哪里开始哪里结尾呢?再次以横向向右运动为例,设置left ,right的初始值为0, n -1 ,然后这2个就是边界,这2个值的是会变的,他们变的原因与横向向右运动up变的原因相同。

算法证明:

无证明,观察得到。

代码:


class Solution:
    def generateMatrix(self, n):
        pass
        direction=0
        
        up=left=0
        down,right=n-1,n-1
        matrix=[[0 for i in range(n)] for j in range(n)]
        
        #生成器
        nums=range(1,n**2+1)
        item=0
        #向ans里按螺旋顺序添加
        while up<=down and left<=right:
            
            if direction==0:
                for i in range(left,right+1):
                    #up在这里表示填充的这一行的行数
                    matrix[up][i]=nums[item]
                    item+=1
                up+=1
            elif direction==1:
                for i in range(up,down+1):
                    #right表示填充的这一行的列数
                    matrix[i][right]=nums[item]
                    item+=1
                right-=1
            elif direction==2:
                for i in range(left,right+1)[::-1]:
                    #down表示填充的这一行的行数
                    matrix[down][i]=nums[item]
                    item+=1
                down-=1
            else:
                for i in range(up,down+1)[::-1]:
                    #left表示填充这一行的列数
                    matrix[i][left]=nums[item]
                    item+=1
                left+=1
            direction=(direction+1)%4
        return matrix

当然了这道题与上道题及其相似,答案只需稍稍修改即可,可以参考:Leetcode 054 螺旋矩阵

JAVA 代码:

	public int[][] generateMatrix(int n) {
		int[][] ret = new int[n][n];
		int left = 0;
		int right = n - 1;
		int up = 0;
		int down = n - 1;
		int count = 1;
		while (left <= right && up <= down) {
			// 右
			for (int j = left; j <= right; j++)
				ret[up][j] = count++;
			up++;
			// 下
			for (int j = up; j <= down; j++)
				ret[j][right] = count++;
			right--;
			// 左
			for (int j = right; j >= left; j--)
				ret[down][j] = count++;
			down--;
			// 上
			for (int j = down; j >= up; j--)
				ret[j][left] = count++;
			left++;
 
		}
		return ret;
	}

C++

#include <iostream>
#include <vector>
 
using namespace std;
vector<vector<int> > generateMatrix(int n)
{
	vector< vector<int> > matrix(n, vector<int>(n));
 
	if (n == 0) 
		return matrix;
 
	int beginX = 0, endX = n - 1;
	int beginY = 0, endY = n - 1;
	int num = 1;
	while (true) 
	{
		for (int j = beginX; j <= endX; ++j) 
			matrix[beginY][j] = num++;
		if (++beginY > endY) 
			break;
		for (int i = beginY; i <= endY; ++i) 
			matrix[i][endX] = num++;
		if (beginX > --endX) 
			break;
		for (int j = endX; j >= beginX; --j) 
			matrix[endY][j] = num++;
		if (beginY > --endY) 
			break;
		for (int i = endY; i >= beginY; --i) 
			matrix[i][beginX] = num++;
		if (++beginX > endX)
			break;
	}
	return matrix;
}
int main()
{
	vector<vector<int>> vec;
	int n=3;
	vec=generateMatrix(n);
	vector<vector<int>>::iterator pp;  
    vector<int>::iterator it;  
    for(pp=vec.begin();pp<vec.end();pp++)  
    {  
        for (it=(*pp).begin();it<(*pp).end();it++)  
        {  
            cout<<*it<<" ";  
        }  
        cout<<endl;  
    }  
	
	return 0;
}

总结:按一定顺序去操作数组的时候,要善于发现操作的规律,比如这一题,观察到了开始位置的坐标,结束位置的纵坐标的话就会非常好做。

猜你喜欢

转载自blog.csdn.net/weixin_41958153/article/details/81213618