矩阵的题目,一般逻辑较为清晰,但实行起来比较复杂,需要考虑周到,特别是越界问题;
T 1:顺时针打印二维数组
这个问题看起来很容易,逻辑清晰,但实现起来还是复杂些,要考虑到不能重复打印,超出边界;
#include <iostream>
#include <vector>
using namespace std;
void printMatrix(vector<vector<int>> a)
{
int leftuprow = 0, leftupcol = 0, rightdownrow = a.size()-1, rightdowncol = a[0].size()-1;
while (leftuprow <= rightdownrow && leftupcol <= rightdowncol)
{
int r = leftuprow;
int c = leftupcol;
while (c <=rightdowncol)
{
cout << a[r][c++]<<" ";
}
c = rightdowncol;
r = leftuprow+1;
while (r <= rightdownrow)
{
cout << a[r++][c] << " ";
}
r = rightdownrow;
c = rightdowncol - 1;
while (c >= leftupcol)
{
cout << a[r][c--]<<" ";
}
c = leftupcol;
r = rightdownrow - 1;
while (r > leftuprow)
{
cout << a[r--][c] << " ";
}
leftupcol++;
leftuprow++;
rightdowncol--;
rightdownrow--;
}
}
int main()
{
vector<vector<int>> test;
for(int i=1;i<=12;i++)
{
vector<int> temp;
while (i%4)
{
temp.push_back(i++);
}
temp.push_back(i);
test.push_back(temp);
}
printMatrix(test);
return 0;
}
T 2:将0所在的行列清零
如果矩阵中某个元素为0,则将其所在行和列清零;
可能会想到,我一边遍历矩阵,遇到0就将它所在行列全部清0;
但这样存在一个问题:如果某一行有多个0,遇到第一个0,会将本行和该列清0,那么循环遍历下去,这一行剩下的都是0,会将这些本不该清0的列都清0;
思路:把每个值为0的位置标记,最后统一对它们所在的行和列清0;
#include <iostream>
#include <vector>
using namespace std;
void setZero(vector<vector<int>> &a)
{
vector<vector<int>> result;
int lenRow=a.size(),lenCol=a[0].size();
for(int i=0;i<lenRow;i++)
{
for(int j=0;j<lenCol;j++)
{
if(a[i][j]==0)
{
vector<int> temp;
temp.push_back(i);
temp.push_back(j);
result.push_back(temp);
}
}
}
for(auto r:result)
{
int row=r[0],col=r[1];
for(int i=0;i<lenCol;i++)
{
a[i][col]=0;
}
for(int i=0;i<lenRow;i++)
{
a[row][i]=0;
}
}
}
int main()
{
vector<vector<int>> test;
for(int i=1;i<=16;i++)
{
vector<int> temp;
while (i%4)
{
temp.push_back(i++);
}
temp.push_back(i);
test.push_back(temp);
}
test[1][2]=0;
test[2][1]=0;
setZero(test);
for(auto a:test)
{
for(auto aa:a)
{
cout<<aa<<' ';
}
cout<<endl;
}
return 0;
}
T 3:Z字形打印
void Z(vector<vector<int>> &a)
{
int r = 0, m = a.size();//m=最大行数
int c = 0, n = a[0].size();//n=最大列数
bool dir = true; //控制方向,true为向上,false为向下
while (r < m && c < n)
{
//从左下到右上,走上坡
if (dir)
{
cout << a[r][c] << ' ';
if (r == 0 && c < n - 1) //到第一行,但未到列边界,只能往右走
{
dir = !dir;
c++;
continue;
}
else if (r < m - 1 && c == n - 1) //到最后一列,未到最后一行,只能向下走
{
dir = !dir;
r++;
continue;
}
else
{
r--;
c++;
}
}
else //相反,走下坡
{
cout << a[r][c] << ' ';
if (c == 0 && r < m - 1) //到第一列,未到最后一行,只能往下走
{
dir = !dir;
r++;
continue;
}
else if (r == m - 1 && c < n - 1) //到最后一行,未到最后一列,只能向右走
{
dir = !dir;
c++;
continue;
}
else
{
r++;
c--;
}
}
}
}
T 4:子数组的最大累加和
给定一个数组,返回子数组的最大累加和;
如 a = {1,-2,3,5,-2,6,-1};所有的子数组中[3,5,-2,6]可以累加出最大的和12;
思路:若累加到当前数的和sum为负,那么比较sum和max,若sum比max大,则更新max,并中断此次累加操作(因为无论下个数next是正是负,sum+next都比next小),从下一个数开始累加;
若加到当前数的和sum为正,则继续累加下去,每次累加比较和max的大小;
int maxSubArray(vector<int> &nums)
{
int len = nums.size();
if (len == 0)
return 0;
int sum = 0, maxSum = nums[0];
for (int i = 0; i < len; i++)
{
sum += nums[i];
if (sum > maxSum)
maxSum = sum;
if (sum < 0)
{
sum = 0;
}
}
return maxSum;
}
T 5:矩阵的乘法
vector<vector<int>> mutMatrix(vector<vector<int>> m1, vector<vector<int>> m2)
{
int n = m1.size(); //矩阵1的行数
int m = m1[0].size(); //矩阵1的列数,矩阵2的行数肯定和矩阵1的列数相同
int p = m2[0].size(); //矩阵2的列数
vector<vector<int>> result;
for (int i = 0; i < n; i++)
{
vector<int> temp;
for (int j = 0; j < p; j++)
{
int sum = 0;
for (int k = 0; k < m; k++)
{
sum += m1[i][k] * m2[k][j];
}
temp.push_back(sum);
}
result.push_back(temp);
}
return result;
}