Leetcode算法题:几道二维数组题

对角线算法可以进一步合并,但不合并的话可读性更好,这里就不合并了。

一、对角线遍历

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

 

示例:

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

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

解释:

 

说明:

  1. 给定矩阵中的元素总数不会超过 100000 。
class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
	vector<int> out;
	int rows = matrix.size();
	if (rows == 0) return out;
	int cols = matrix[0].size();
	if (cols == 0) return out;
	//初始方向
	int horizon = 1;
	int sum = 0;
	int pos = 0;//方向正,则表示x,方向负,则表示y
	for (int i = 0; i<rows+cols-1; i++) {
	    if (horizon == 1) {
	        //正方向的时候,pos是x坐标,起点在左边界或下边界
		pos = (sum < rows) ? 0 : (sum - rows + 1);//确认起点
		//遍历从起点开始直到边界
		while (pos<cols && sum-pos>-1) {
		    out.push_back(matrix[sum - pos][pos]);
		    pos++;
		}
		//遍历完了,转向并进入下一条对角线
		sum++;
		horizon *= -1;
	    }
	    else{
		//反方向的时候,pos是y坐标,起点在右边界或上边界
		pos = (sum < cols) ? 0 : (sum - cols + 1);//确认起点
		//遍历从起点开始直到边界
		while (pos<rows && sum-pos>-1) {
		    out.push_back(matrix[pos][sum-pos]);
		    pos++;
		    }
		//遍历完了,转向并进入下一条对角线
		sum++;
		horizon *= -1;
	    }
	}
	return out;
    }
};

 二、螺旋矩阵

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

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

示例 2:

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

 

class Solution {
public:
    //确认起点、方向、终点;遇到终点时时,更新起点、方向、终点(边界值)
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> out;
        int rows = matrix.size();
        if (rows == 0) return out;
        int cols = matrix[0].size();
        if (cols == 0) return out;

        int x_min = 0;
        int x_max = cols - 1;
        int y_min = 0;
        int y_max = rows - 1;
        int x_off = 1;
        int y_off = 0;
        int x = 0;
        int y = 0;
        int counter = 0;
        while (counter<rows*cols) {
	    out.push_back(matrix[y][x]);
	    counter++;
	    x += x_off;
	    y += y_off;
	    //到右边界
	    if (x>x_max) {
	        x = x_max;
	        y++;
	        x_off = 0;
	        y_off = 1;
	        y_min++;
	    }
	    //到下边界
	    else if (y>y_max) {
	        x--;
	        y = y_max;
	        x_off = -1;
	        y_off = 0;
	        x_max--;
	    }
	    //到左边界
	    else if (x<x_min) {
	        x = x_min;
	        y--;
	        x_off = 0;
	        y_off = -1;
	        y_max--;
	    }
	    //到上边界
	    else if (y<y_min) {
	        x++;
	        y = y_min;
	        x_off = 1;
	        y_off = 0;
	        x_min++;
	    }
        }
	return out;
    }
};

 三、杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

在杨辉三角中,每个数是它左上方和右上方的数的和。

示例:

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]
class Pascaltriangle {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> out;
	if (numRows == 0) return out;
	for (int i = 0; i<numRows; i++) {
	    out.push_back(vector<int>(i + 1, 1));
	    for (int j = 1; j<i; j++) {
	        out[i][j] = out[i - 1][j] + out[i - 1][j - 1];
	    }
	}
	return out;
    }
};

 

 

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值