LeetCode【学习计划】:【数据结构】
566. 重塑矩阵
LeetCode: 566. 重塑矩阵
简 单 \color{#00AF9B}{简单} 简单
在 MATLAB 中,有一个非常有用的函数
reshape
,它可以将一个m x n
矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。
给你一个由二维数组mat
表示的m x n
矩阵,以及两个正整数r
和c
,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的reshape
操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
示例 1:
输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]
示例 2:
输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
-1000 <= mat[i][j] <= 1000
1 <= r, c <= 300
前言
题目中并没有提到r
和c
的值一定能使mat
重塑,也就是说r*c
可能大于或者小于mat
的总量。实测出来LeetCode对这种情况是直接返回mat
,因此我们也选择直接返回mat
。
方法1:一维数组
我们希望找到一个能将位于(i,j)
的元素直接从原矩阵mat
映射到答案矩阵ans
的关系式。我们可以从mat
先置为一维数组,再从一维数组转化为二维数组的两个过程去思考。
首先,设矩阵mat
的行数为m
,列数为n
。不难得出,将mat
置为一维数组后,位于(i,j)
的元素在一维数组中的位置为x=i*n+j
。同时,这也表明从x
往回映射时,元素的坐标为(i,j)==(x/i,x%i)
。
其次,题目给出了答案数组的行数为r
,列数为c
。也不难得出,x
往新数组映射时,元素的坐标为(x/c,x%c)
。
所以我们可以得到如下的映射关系:
a n s [ i / c ] [ i % c ] = m a t [ i / n ] [ i % n ] ans[i/c][i\%c] = mat[i/n][i\%n] ans[i/c][i%c]=mat[i/n][i%n]
一维数组的长度即为m*n
。因此循环的次数,也就是i
的范围,也是m*n
#include <vector>
using namespace std;
class Solution
{
public:
vector<vector<int>> matrixReshape(vector<vector<int>> &mat, int r, int c)
{
const int m = mat.size(), n = mat[0].size();
const int size = m * n;
if (size != r * c)
{
return mat;
}
vector<vector<int>> ans(r, vector<int>(c));
for (int i = 0; i < size; i++)
{
ans[i / c][i % c] = mat[i / n][i % n];
}
return ans;
}
};
复杂度分析
-
时间复杂度: O ( r × c ) O(r \times c) O(r×c)
-
空间复杂度: O ( 1 ) O(1) O(1)。答案数组不计算在内。
参考结果
Accepted
57/57 cases passed (8 ms)
Your runtime beats 87.68 % of cpp submissions
Your memory usage beats 83.09 % of cpp submissions (10.3 MB)
118. 杨辉三角
LeetCode: 118. 杨辉三角
简 单 \color{#00AF9B}{简单} 简单
给定一个非负整数
numRows
,生成「杨辉三角」的前numRows
行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例 2:
输入: numRows = 1
输出: [[1]]
提示:
1 <= numRows <= 30
方法1:数学
我们可以从「杨辉三角」的这个特点入手:每个数字等于上一行的左右两个数之和,也就是:
a
n
s
[
i
]
[
j
]
=
a
n
s
[
i
−
1
]
[
j
−
1
]
+
a
n
s
[
i
−
1
]
[
j
]
ans[i][j]=ans[i-1][j-1]+ans[i-1][j]
ans[i][j]=ans[i−1][j−1]+ans[i−1][j]
#include <vector>
using namespace std;
class Solution
{
public:
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> ans;
ans.reserve(numRows);
for (int i = 0; i < numRows; i++)
{
vector<int> row(i + 1);
row[0] = row[i] = 1;
if (i >= 2)
{
for (int j = 1; j < i; j++)
{
row[j] = ans[i - 1][j - 1] + ans[i - 1][j];
}
}
ans.emplace_back(row);
}
return ans;
}
};
复杂度分析
-
时间复杂度: O ( n u m R o w s 2 ) O(numRows^2) O(numRows2)
-
空间复杂度: O ( 1 ) O(1) O(1)。答案数组不计算在内,我们只需要常量空间来存储若干变量。
参考结果
Accepted
14/14 cases passed (0 ms)
Your runtime beats 100 % of cpp submissions
Your memory usage beats 97.77 % of cpp submissions (6.2 MB)