矩阵算法的介绍和实现

一. 介绍

首先我们要清楚矩阵是什么:矩阵是一个按照长方阵列排列的复数或实数集合

1> 定义

  1. 定义:m×n矩阵为m×n个数排成的m行n列的表格,当m=n时,矩阵A称为n阶方阵或者n阶矩阵
  2. 零矩阵:矩阵所有元素都为0。
  3. 同型矩阵:A矩阵为m×n矩阵,B矩阵为s×t矩阵,如果m=s,n=t,A和B即为同型矩阵。
  4. A和B相等:两个同型矩阵对应的元素都相等
  5. |A|(detA):n阶方阵A构成的行列式。

以上就为3*4的一个矩阵

2> 运算

  1. 加法:两个同型矩阵可以相加
  2. 数乘:k为数,数乘时是将k与矩阵中每一个元素进行乘积
  3. 乘法:设A是一个m×s矩阵,B是一个s×t矩阵(A的列数=B的行数),则A、B可乘,且乘积AB是一个m×t矩阵,记为C。其中C的第i行、第j列元素Cij是A的第i行s个元素和B的第j列s个对应元素两两乘积之和。(每个新元素等于原来两个矩阵对应行元素逐个乘上对应列元素,再加和
  4. 转置:将m×n型矩阵A=[aij]m×n的行列互换的到的n×m矩阵[aji]n×m,称为A的转置矩阵。
  5. 矩阵多项式:设A是n阶矩阵,f(x)=amxm+……+a1x+a0是x的多项式,则称 amAm+am-1Am-1+……+a1A+a0E为矩阵多项式,记为f(A)

3> 性质


Ⅰ.加法

  1. A+B=B+A
  2. (A+B)+C=A+(B+C)
  3. A+O=A (其中O是元素全为0的同型矩阵)
  4. A+(-A)=O

Ⅱ.数乘

  1. k(mA)=(km)A=m(kA)
  2. (k+m)A=kA+mA
  3. k(A+B)=kA+kB
  4. 1A=A
  5. 0A=O

Ⅲ.乘法

  1. (AB)C=A(BC)
  2. A(B+C)=AB+AC
  3. (B+C)A=BA+CA(注意顺序不可以颠倒

Ⅳ.转置

  1. (A+B)T=AT+BT
  2. (kA)T=kAT
  3. (AB)T=BTAT
  4. (AT)T=A

注意

  1. AB≠BA
  2. A≠O,B≠O,但有可能AB=O
  3. AB=AC,A≠O不能推出B=C
  4. (A+B)(A+B)=A2+AB+BA+B2
  5. (A+E)2=A2+2A+E
  6. (A+E)(A-E)=A2-E2
  7. AB=O 可推出B的列向量是AX=0的解

二. 算法

矩阵类题目常常把思考的维度从一维扩展到二维,需要考虑的边界条件也相应增多,以矩阵为背景的题目大多有动态规划类型、记忆搜索类型、深度优先搜索类型等等。

实例一:

题目描述:有x*y大小的格子,只能从左往右、从上往下走,问从左上到右下有多少种走法

示例

一个2*3的矩阵,

                     1 2 3

                     4 5 6

从1出发走到6,则可能的走法为:1 2 3 6, 1 2 5 6, 1 4 5 6共有三种。

解决思路:从最后一个格子进行倒推,需要找到关系方程:res[i][j] = res[i-1][j] + res[i][j-1],然后可以用递归或者非递归的方法进行求解。

递归:

public static int numPath(int x, int y) {
    if(x==1||y==1) return 1;
    return numPath2(x-1, y) + numPath2(x, y-1);
  }
 非递归:

public static int numPath(int x, int y) {
    if(x == 1 || y == 1){
       return 1;
    }
    int[][] res = new int[x][y];
    for(int i = 0; i < x; i++){
       res[i][0] = 1;
    }
    for(int i = 0; i < y; i++){
       res[0][i] = 1;
    }
    for(int i = 1; i < x; i++) {
      for(int j = 1; j < y; j++) {
        res[i][j] = res[i-1][j] + res[i][j-1];
      }
    }
    return res[x-1][y-1];
  }

 示例二:

给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

使用两个标记变量

思路和算法

在代码中,我们用两个标记数组分别记录每一行和每一列是否有零出现,我们首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列,然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean flagCol0 = false, flagRow0 = false;
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                flagCol0 = true;
            }
        }
        for (int j = 0; j < n; j++) {
            if (matrix[0][j] == 0) {
                flagRow0 = true;
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        if (flagCol0) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
        if (flagRow0) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }
    }
}

题出处:73. 矩阵置零 - 力扣(LeetCode) 

❤️❤️❤️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值