当前位置: 首页 > wzjs >正文

优化网站 主题大学思政类网站建设

优化网站 主题,大学思政类网站建设,网页版攻速传奇,百度指数的使用方法1,按对角线进行矩阵排序 题目链接:3446. 按对角线进行矩阵排序 - 力扣(LeetCode) 【题目描述】 对于一个m*n的矩阵grid,要求对该矩阵进行 变换,使得变换后的矩阵满足: 主对角线右上的所有对角…

1,按对角线进行矩阵排序

题目链接:3446. 按对角线进行矩阵排序 - 力扣(LeetCode)

【题目描述】

对于一个m*n的矩阵grid,要求对该矩阵进行 变换,使得变换后的矩阵满足:

主对角线右上的所有对角线上,元素升序排列。

主对角线左下的所有对角线上,元素降序排列。

【思路】

对于一个矩阵grid,我们可以发现,从右上角到左下角的所有对角线中,同一条对角线上的元素满足:行号i减去列号j是一个定值。

令k=i-j+n,这里加n是为了避免k出现负数。

对于右上角的对角线,k=i-j+n=1。对于左下角的对角线k=m+n-1;

所以,我们可以枚举k=1,2,3,......,m+n-1;相当于从右上角开始,到左下角结束,遍历每条对角线。

 接下来需要求出每条对角线上j的取值范围,从而可以遍历对角线上的元素 。

k=i-j+n——>j=i+n-k。

当i=0时,j取最小值,j=n-k。但是j可能会出现负数,所以最小的j=max(0,n-k)。

当i=m-1时,j取最大值,j=m+n-1-k。但是j可能会超出范围,所以最大的j=min(n-1,m+n-1-k)。

对于一个矩阵,如何区别主对角线的右上和左下???

我们可以通过j的最小值来确定,观察上图可看出,对于主对角线右上的对角线来说,j的最小值都是大于0的,相反,对于主对角线走下的对角线来说,j的最小值都是等于0的。所以可以 以这点来做区分。

接下来就可以进行模拟了:

枚举k=1,2,3......,m+n-1;

求出每条对角线上j的范围。将该对角线上的 元素加入数组 。排序后(升序或者降序)写回原数组。

【代码】

class Solution {
public:vector<vector<int>> sortMatrix(vector<vector<int>>& grid) {//k=i-j+n;int m=grid.size(),n=grid[0].size();//右上角k=1//左下角k=m+n-1for(int k=1;k<m+n;k++){//计算当前对角线的最小值和最大值int min_j=max(n-k,0);int max_j=min(m+n-k-1,n-1);vector<int> a;for(int j=min_j;j<=max_j;j++){a.push_back(grid[k+j-n][j]);}//主对角线右上 升序排列if(min_j>0){ranges::sort(a);}else{//主对角线左下  降序排列ranges::sort(a,greater<int>());}//写回数组for(int j=min_j;j<=max_j;j++){grid[k+j-n][j]=a[j-min_j];}}return grid;}
};

时间复杂度:O(N^2*logN)

空间复杂度:O(N) 

2,将矩阵按对角线进行排序

题目链接:1329. 将矩阵按对角线排序 - 力扣(LeetCode)

本题和上题思路一致,但是要求每条对角线都按升序排列。

class Solution {
public:vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {int m=mat.size(),n=mat[0].size();for(int k=1;k<m+n;k++){int min_j=max(n-k,0);int max_j=min(m+n-k-1,n-1);vector<int> a;for(int  j=min_j;j<=max_j;j++)a.push_back(mat[k+j-n][j]);ranges::sort(a);for(int j=min_j;j<=max_j;j++)mat[k+j-n][j]=a[j-min_j];}return mat;}
};

 3,对角线上不同值的数量差

题目链接:2711. 对角线上不同值的数量差 - 力扣(LeetCode)

【题目描述】 

对于一个大小为m*n的矩阵grid,返回一个同等规模的数组ans,其中ans[i][j]表示:

在矩阵grid中,grid[i][j]左上角对角线中不同值的数量和右下角对角线不同值的数量的差值,对最后结果再取绝对值。

【思路1】暴力计算 :

遍历grid[i][j]的每一个元素,计算topLeft[i][j]和bottomRight[i][j]。

首先我们可以定义一个unordered_set容器,遍历元素的时候,将元素加入到该容器中。

计算topLeft[i][j]:从[i,j]位置开始,遍历左上角对角线,进行[i--,j--]操作。直到矩阵的边界。

这个过程中,把遍历到的元素加入到容器中,最终topLeft[i][j]就是容器的大小。

计算bottomRight[i][j]:从[i,j]位置开始,遍历右下角对角线,进行[i++,j++]操作。直到矩阵的边界。这个过程中,把遍历到的元素加入到容器中 ,最终bottomRight[i][j]就是容器的大小。

【思路1代码】

class Solution {
public:vector<vector<int>> differenceOfDistinctValues(vector<vector<int>>& grid) {int m=grid.size(),n=grid[0].size();vector<vector<int>> ans(m,vector<int>(n,0));unordered_set<int> st;//天然的去重,容器的大小就是 不同值的数量for(int i=0;i<m;i++){for(int j=0;j<n;j++){st.clear();//查找左上角 不同值的个数for(int x=i-1,y=j-1;x>=0&&y>=0;x--,y--)st.insert(grid[x][y]);int topLeft=st.size();//查找右下角 不同值的个数st.clear();for(int x=i+1,y=j+1;x<m&&y<n;x++,y++)st.insert(grid[x][y]);int bottomRight=st.size();ans[i][j]=abs(topLeft-bottomRight);}}return ans;}
};

时间复杂度:O(m*n*(min(m,n)),m和n分别为grid的行数和列数。

计算一个topLeft和bottomRight需要O(min(m,n))的时间。 

【思路2】

该方法就要使用到前面两道题对 对角线的操作思路。

思路一的方法:对于同一条对角线,会遍历多次。比如求ans[0][0],会遍历一次主对角线,求ans[1][1]的时候,会遍历一次主对角线,求ans[1][1]也会遍历一次主对角线,所以存在多次重复遍历。

我们可以按照前面两道题的思路。

将每条对角线看成是一个一维数组d。

对于d[i]来说:

topLeft[i]是d[i]左侧不同值的数量,我们可以从左向右遍历,将元素加入到哈希集合中,直到遍历到d[i],此时topLeft就是哈希集合的大小。

bottomRight[i]是右侧不同值的数量 ,我们可以从右向左遍历,将元素加入到哈希集合中,直到遍历到d[i],此时bottomRight就是哈希集合的大小。

【思路2代码】

class Solution {
public:vector<vector<int>> differenceOfDistinctValues(vector<vector<int>>& grid) {int m=grid.size(),n=grid[0].size();unordered_set<int> st;vector<vector<int>> ans(m,vector<int>(n));//枚举k 从1到m+n-1//k=i-j+nfor(int k=1;k<m+n;k++){//求出j的范围int min_j=max(n-k,0);//i=0时,j=n-k,但不能是负数int max_j=min(m+n-k-1,n-1);//i=m-1时,j=m+n-1-k,但不能超出范围st.clear();//计算左侧不同值的数量 topLeft//从 左向右遍历for(int j=min_j;j<=max_j;j++){int i=k+j-n;ans[i][j]=st.size(); //topLeft[i][j]=st.size();st.insert(grid[i][j]);}//计算右侧最大值的数量  bottomRight//从右向左遍历st.clear();for(int j=max_j;j>=min_j;j--){int i=k+j-n;ans[i][j]=abs(ans[i][j]-(int)st.size());//st.size()返回值时size_tst.insert(grid[i][j]);}}return ans;}
};

时间复杂度:O(m*n),每个单元格访问两次。

4,对角线遍历

题目链接:498. 对角线遍历 - 力扣(LeetCode)

 【思路】

我们前面所讲题的对角线遍历,对角线都是从左上角到右下角的一条线。都是主对角线

而本题 方向相反,都是副对角线。我们可以将数组中的每一行进行翻转,就可以转化成主对角线了。

之后,使用前面的思想,遍历每条对角线。

k=i-j+n;枚举k,从1到m+n-1;

 求出每条对角线j的最大值和最小值。

对于每条对角线,我们可能需要从下到上遍历,也可能需要从上到下遍历。对应的j就需要从大到小遍历,也可能需要从小到大遍历。

我们可以定义一个变量flag,flag=1时从下到上遍历,也就是j从从大到小遍历。

flag=0时,从上到下遍历,也就是j从小到大遍历。

开始时,需要从下到上遍历,flag设为1.

【代码】

class Solution {
public:vector<int> findDiagonalOrder(vector<vector<int>>& mat) {int m=mat.size(),n=mat[0].size();//翻转每一行for(auto& v:mat){reverse(v.begin(),v.end());}vector<int> ans;int flag=1;//k=i-j+n//1,2,3......m+n-1//枚举k,枚举每一条对角线for(int k=1;k<m+n;k++){//求出j的最小值和最大值int min_j=max(n-k,0);int  max_j=min(m+n-k-1,n-1);//从下到上遍历  对于j是从大到小遍历if(flag){for(int j=max_j;j>=min_j;j--){int i=k+j-n;ans.push_back(mat[i][j]);}}else  //从上到下遍历  对应的j从小到大遍历{for(int  j=min_j;j<=max_j;j++){int i=k+j-n;ans.push_back(mat[i][j]);}}flag^=1;}return ans;}
};

总结:

对角线的遍历(主对角线):对于一个m*n的矩阵。

在同一条对角线上的元素,行号i减去列号j是一个定值。k=i-j+n;

k的值从1开始到m+n-1。就是主对角线从右上角对角线开始,一直到左下角对角线。

遍历对角线时,我们只需求出j的范围即可,i=k+j-n。但需要注意j不能小于0,也不能超出数组的范围。然后就可以对这条对角线进行操作了。

http://www.dtcms.com/wzjs/560934.html

相关文章:

  • 网站前后端全部做需要多少钱建设银行对公网站打不开
  • 六安建设局网站专业网站制作仪表多少钱
  • 做网站都有什么功能网站与域名
  • 小榄网站安徽省建设厅官方网站各处室
  • 怎样看一个网站的信息吗wordpress umeditor
  • 网站开发有哪些术语郫都区规划建设局网站
  • iis网站权限怎么设置手机网站封装用户体验
  • 网站维护细则网站内部链接怎么做的
  • 购买空间后怎么上传网站政务网站建设方案
  • 建设网站哪间公司比较好用网站模板建站
  • 家具设计作品集网站建设优化价格
  • 网站被做跳转怎么办网站分为的风格
  • html5网站建站书网站建设后台怎么弄
  • 厦门百度网站建设企业vi设计案例欣赏
  • 建设网站怎么加购物车大朗做网站的
  • 企业网站制作建站公司江西城乡建设部网站首页
  • php无版权企业网站管理系统自动生成app
  • 公司营销型网站建设查找北京国互网网站建设
  • 莱芜市网站建设设计刷外链工具
  • 怎么做非法彩票网站wordpress下载页插件下载
  • 网站策划书ppt1688精品货源网站入口
  • 网站可以分为哪些类型中国十大品牌设计公司
  • 珠宝设计制作培训梅州网站优化
  • 网站建设就找奇思网络免费企业网站管理系统
  • 响应式网站用什么做WordPress自动采集豆瓣评分
  • 深圳哪里有做网站网站需求分析报告
  • 江苏网站开发盘锦做网站建设的
  • wordpress 建站容易吗建设网站是否应当摊销
  • 东营市建设项目工伤保险是哪个网站东圃做网站的公司
  • 做教育网站有什么好处论坛程序做导航网站