【LeetCode学习计划】《数据结构入门-C++》第4天 数组

LeetCode【学习计划】:【数据结构】



566. 重塑矩阵

LeetCode: 566. 重塑矩阵

简 单 \color{#00AF9B}{简单}

MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。
给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 rc ,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 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

前言

题目中并没有提到rc的值一定能使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[i1][j1]+ans[i1][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)
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亡心灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值