前言

第三周我们计划刷关于矩阵的题目。

此次参与刷题的共五人(嘟嘟、琼琼、东东、大智、博主)。

首次把宿舍的白板用上了。。

正题

28.搜索二维矩阵

每行都是有序的,且下一行第一个元素比上一行最后一个元素大。

我们先对行二分,再对列二分。算法复杂度O(logn*logm)

38.搜索二维矩阵2

每一行从左到右递增,每一列从上至下递增。

本题的难点在于无法比较左下和右上的值谁大。

我们可以直接比较右上角的数字(或者左下角的数字),如果比右上角大,那么排除了第一行;如果比右上角小,排除了第一列。

PS:三角兽面试题

代码:

class Solution {
public:/** @param matrix: A list of lists of integers* @param target: An integer you want to search in matrix* @return: An integer indicate the total occurrence of target in the given matrix*/int searchMatrix(vector<vector<int>> &matrix, int target) {// write your code hereint m = matrix.size(),res=0;if(m==0) return res;int n = matrix[0].size();int x=0,y=n-1;while(x<m&&y>=0){if(matrix[x][y]<target) ++x;else if(matrix[x][y]>target) --y;else ++res,++x;}return res;}
};

161.旋转图像

四个位置(i,j) (j,n-1-i) (n-1-i,n-1-j) (n-1-j,i)依次交换即可。

162.矩阵归0

挑战是O(1)的空间。

用第一行表示哪一列为0,用第一列表示哪一行为0,但是第一行第一列是表示某一行还是某一列呢?因此需要单加一个变量表示第一行或者第一列是否归0。

PS: 第四范式 面试题。

185.矩阵的之字型遍历

这题是当年考研的预面试题目,当时相当于画了一个状态机做的。可以参考:考研上机题 的第五题。

有四个方向。右、左下、下、右上。

左下和右上可以继续,其他的方向需要改变成下一个。

代码:

class Solution {
public:/** @param matrix: An array of integers* @return: An array of integers*/int dir[4][2] = {{0,1},{1,-1},{1,0},{-1,1}};int m,n;vector<int> res;vector<vector<bool> > vis;void dfs(vector<vector<int> > matrix,int x,int y,int d){int cur_x,cur_y;cur_x=x+dir[d][0],cur_y=y+dir[d][1];if(cur_x>=0&&cur_x<m&&cur_y>=0&&cur_y<n&&!vis[cur_x][cur_y]){res.push_back(matrix[cur_x][cur_y]);vis[cur_x][cur_y] = true;if(d&1) dfs(matrix,cur_x,cur_y,d);dfs(matrix,cur_x,cur_y,(d+1)%4);dfs(matrix,cur_x,cur_y,(d+2)%4);dfs(matrix,cur_x,cur_y,(d+3)%4);//其他方向都不行,只能顺着一个方向dfs(matrix,cur_x,cur_y,d);}}vector<int> printZMatrix(vector<vector<int>> &matrix) {// write your code herem = matrix.size();if(m==0) return res;n = matrix[0].size();for(int i=0;i<m;++i)vis.push_back(vector<bool>(n,false));vis[0][0]=true;res.push_back(matrix[0][0]);dfs(matrix,0,0,0);dfs(matrix,0,0,2);return res;}
};

364.接雨水2(好题!)

我们可以先做363.接雨水,一维的只需要记录每个位置往左边能到的最大值和往右边能到的最大值(里面选一个小的减去当前高度)就是这个位置能接的水,然后把所有位置能接的水加起来即为结果。

代码:

class Solution {
public:/** @param heights: a list of integers* @return: a integer*/int trapRainWater(vector<int> &heights) {// write your code hereint len = heights.size();if(len<3) return 0;int res=0,tmp=0;vector<int> l(len),r(len);for(int i=0;i<len;++i){l[i]=tmp;tmp=max(tmp,heights[i]);}tmp=0;for(int i=len-1;i>=0;--i){r[i]=tmp;tmp=max(tmp,heights[i]);}for(int i=1;i<len-1;++i)res+=max(min(l[i],r[i])-heights[i],0);return res;}
};

但是二维的就没这么简单了,如果使用l,r,d,u表示四个方向的最大值的话会出问题(比如水可以从右下漫出。。)

如果一个位置能找到往外流出的路径,那么这个位置不能接水。

我们可以使用BFS+优先队列来解决这个问题。

1.首先把边界的点加入到队列中,每次出队选择高度最低的出队。

2.记录之前的最大值,如果当前值比最大值小,表示可以装水。

【如果可以漫出,那么之前的最大值一定<=当前值】

【队列里的元素和之前最大的元素是边界,都>=之前的最大值】

PS:使用tuple会超时 (换成了pair 压缩行和列)

参考:[LeetCode] Trapping Rain Water II 收集雨水之二

代码:

class Solution {
public:/** @param heights: a matrix of integers* @return: an integer*/int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};int trapRainWater(vector<vector<int>> &heights) {// write your code hereint m = heights.size();if(m<3) return 0;int n = heights[0].size();if(n<3) return 0;vector<vector<bool> > vis(m,vector<bool>(n,false));priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;for(int i=0;i<m;++i)for(int j=0;j<n;++j)if(i==0||i==m-1||j==0||j==n-1){vis[i][j]=true;q.push(make_pair(heights[i][j],i*n+j));}int res=0,max_h=0;while(!q.empty()){pair<int,int> t = q.top();q.pop();int x = t.second/n, y=t.second%n, h = t.first;res+=max(0,max_h-h);max_h = max(max_h,h);for(int i=0;i<4;++i){int cx=x+dir[i][0],cy=y+dir[i][1];if(cx>=0&&cx<m&&cy>=0&&cy<n&&!vis[cx][cy]){vis[cx][cy]=true;q.push(make_pair(heights[cx][cy],cx*n+cy));}}}return res;}
};

374.螺旋矩阵

和185.矩阵的之字型遍历类似,四个方向(右、下、左、上)

389.判断数独是否合法

判断每行、每列、每个格子即可。

401.排序矩阵中的从小到大第k个数

每一行递增,每一列也递增。

把所有的元素排序,找第k个,这样的复杂度是O(n*logn)

而题目的挑战是O(k*logn)。

我们使用最小堆(优先队列)来实现,每次把元素的右边和下边的元素入队(比当前元素大一点点)。其实入队的操作就是在调整最小堆。【最小堆的实现使用数组vector】

405.和为0的子矩阵

我们可以使用dp[i][j]表示【以(0,0)表示左上,(i,j)表示右下】矩阵的面积。

那么dp[i][j] = dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+matrix[i-1][j-1]; (容斥原理,dp[i-1][j-1]算了两遍,故要减去一次)

那么我们可以枚举起点(左上)和终点(右下)的位置,这样的复杂度是O(n^4)。

而题目的挑战是O(n^3)。

我们可以联想到上上篇博客中的138.子数组之和问题。138是要在一维数组中找出和为0的子数组,一般的做法是枚举起始位置和结束位置【复杂度O(n^2)】,而当时的做法是遍历一遍,使用一个map把前缀和存入map中,如果之前存在了,那么已经找到了。【复杂度变为O(n)】

同样的做法可以应用于这个题,我们只需要枚举任意两行(O(n^2)),遍历每一列然后使用map存矩阵的前缀和即可。这样复杂度就变为了O(n^3)

代码:

class Solution {
public:/** @param matrix: an integer matrix* @return: the coordinate of the left-up and right-down number*/vector<vector<int>> submatrixSum(vector<vector<int>> &matrix) {// write your code here//dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1]+a[i][j]vector<vector<int> > res(2,vector<int>(2));int m=matrix.size(),n=matrix[0].size();vector<vector<int> > dp(m+1,vector<int>(n+1,0));for(int i=1;i<=m;++i)for(int j=1;j<=n;++j)dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+matrix[i-1][j-1];map<int,int> mp;for(int i=1;i<=m;++i)for(int j=i;j<=m;++j){ //枚举任意两行mp.clear();mp[0]=0;for(int k=1;k<=n;++k){int tmp = dp[j][k]-dp[i-1][k];// cout<<i<<" "<<j<<" "<<k<<" "<<tmp<<endl; if(mp.find(tmp)!=mp.end()){res[0][0]=i-1,res[0][1]=mp[tmp];res[1][0]=j-1,res[1][1]=k-1;return res;}mp[tmp]=k;}}}
};/*
1 6 13
4 16 15
8 12 20
*/

737.Find Elements in Matrix
寻找在每一行都出现的元素(数据保证只有一个)。

把第一行的放入map,遍历每一行,如果出现过+1。

如果等于m则满足条件。

找到一个trick。

这条数据: [[2,1,3],[3,1,1],[0,3,5]] 没有过(正确是3,我返回的是1,竟然AC了)。。

要防止这个就是在遍历行的时候,每行去个重【可以使用map】即可!

lintcode 矩阵问题(最全的面试矩阵问题)相关推荐

  1. 腾讯郭振宇:腾讯云发布云IoT全栈产品矩阵,详解6大产品及3大案例

    5月21-23日,由云南省人民政府指导,云南省文化和旅游厅.昆明市人民政府.腾讯公司共同主办,腾讯战略升级后打造的规格最高.规模最大的行业生态大会"全球数字生态大会"在昆明隆重举行 ...

  2. Matlab去掉矩阵中的全0行或列

    a=[1 2 3;0 0 0;2 1 6]; %去掉矩阵中的全0行 a(all(a==0,2),:) = []; %去掉矩阵中的全0列 a(all(a==0,1),:) = [];

  3. Leetcode算法Java全解答--73. 矩阵置零

    Leetcode算法Java全解答–73. 矩阵置零 文章目录 Leetcode算法Java全解答--73. 矩阵置零 题目 想法 结果 总结 代码 我的答案 大佬们的答案 测试用例 其他 题目 给定 ...

  4. 矩阵分解(超全整理笔记)

    矩阵分解笔记 文章目录 矩阵分解笔记 矩阵的三个基本分解 长方阵的分解 长方阵的基本分解 长方阵的满秩分解 方阵的分解 Jordan 分解 Schur 分解 矩阵的三角分解 定义 可逆矩阵的三角分解的 ...

  5. 最全Java面试180题:阿里11面试+网易+百度+美团!含答案大赠送!

    网络编程 ISO模型与协议 http1.0:需要使用keep-alive参数来告知服务器端要建立一个长连接 http1.1:默认长连接.支持只发送header信息,可以用作权限请求.支持Host域. ...

  6. 最全技术面试180题:阿里11面试+网易+百度+美团!

    最全技术面试180题:阿里11面试+网易+百度+美团! 网络编程 ISO模型与协议 http1.0:需要使用keep-alive参数来告知服务器端要建立一个长连接 http1.1:默认长连接.支持只发 ...

  7. 矩阵相乘的strassen算法_矩阵乘法的Strassen算法+动态规划算法(矩阵链相乘和硬币问题)...

    矩阵乘法的Strassen 这个算法就是在矩阵乘法中采用分治法,能够有效的提高算法的效率. 先来看看咱们在高等代数中学的普通矩阵的乘法 两个矩阵相乘 上边这种普通求解方法的复杂度为: O(n3) 也称 ...

  8. 【Pytorch神经网络理论篇】 25 基于谱域图神经网络GNN:基础知识+GNN功能+矩阵基础+图卷积神经网络+拉普拉斯矩阵

    图神经网络(Graph Neural Network,GNN)是一类能够从图结构数据中学习特征规律的神经网络,是解决图结构数据(非欧氏空间数据)机器学习问题的最重要的技术. 1 图神经网络的基础知识 ...

  9. matlab 求取矩阵中值,matlab中取矩阵中指定列的值组成新矩阵

    matlab 矩阵中怎么加入冒号,比如我想矩阵A的第一列都为"1:" A(:,1)='1:';再问:不行的再答:用结构矩阵或者单元矩阵试试吧. 诚教:matlab中取矩阵的其中几行 ...

最新文章

  1. 小米note3无线显示电脑连接服务器,小米note3如何连接电脑 小米note3连接电脑没反应怎么办...
  2. SIP穿越NATFireWall解决方案
  3. xarray 笔记:DataArray
  4. 南京信息工程大学c语言实验十报告,南京信息工程大学2014年C语言程序设计实验内容(全部).doc...
  5. 堆上与堆外的内存使用情况
  6. 【HDU - 5882】Balanced Game (找规律,思维)
  7. 为什么清华、北大、麻省理工硕博士,都要逐步推导机器学习算法?
  8. App Domains and dynamic loading
  9. 磁盘设置压缩导致无法将数据库还原到该硬盘的问题
  10. 随身助手API接口网站PHP源码v1.0
  11. [Unity] material was not upgraded. There‘s no upgrader to convert {1} shader to selected pipeline报错
  12. 《论文阅读》PV-RCNN: Point-Voxel Feature Set Abstraction for 3D Object Detection
  13. 2021年网络空间安全学院预推免面试经验总结
  14. 去除PDF文件中的斜体文字水印
  15. 数位dp算法——洛谷p1980
  16. 【在线教程】pdf文件怎么压缩到最小
  17. [内核内存] 反向映射详解
  18. 内存颗粒位宽和容量_内存和内存颗粒是什么关系?
  19. 永恒之蓝漏洞ms17-010
  20. 【C++实现】编译原理 免考小队 FIRSTVT集生成算法

热门文章

  1. 梦幻“玩主”—记新普矽谷科技CEO史朝翔
  2. 09年最好看的电视剧大全_09年最经典的电视剧大全
  3. 证明与计算(3): 二分决策图(Binary Decision Diagram, BDD)
  4. 计算机一级理论知识题,计算机一级考试《理论题》及答案
  5. 如何将文字转换成语音?这三个方法简单、快速、准确率高
  6. open*** 搭建
  7. u盘扫描并修复后文件消失了怎么办?2种方法帮助找回
  8. html实践环节制作调查问卷,HTML大学生暑假社会实践调查问卷源代码
  9. 程序员也需要理财,给不懂理财的朋友整理的理财入门书籍,分享一发
  10. B站视频任意调整倍速