给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法
什么是原地算法?
void setZeroes(int** matrix, int matrixSize, int* matrixColSize) {
int m = matrixSize;
int n = matrixColSize[0];
int row[m], col[n];
memset(row, 0, sizeof(row));
memset(col, 0, sizeof(col));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!matrix[i][j]) {
row[i] = col[j] = true;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (row[i] || col[j]) {
matrix[i][j] = 0;
}
}
}
}
为啥这样写就报错了
void setZeroes(int** matrix, int matrixSize, int* matrixColSize) {
int m = matrixSize;
int n = matrixColSize[0];
int p,q;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!matrix[i][j]) {
p=i;
q=j;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i==p || j==q) {
matrix[i][j] = 0;
}
}
}
}
int row[m], col[n];
memset(row, 0, sizeof(row));
memset(col, 0, sizeof(col));
的作用是?
那能一样吗?上面代码是将所有值为0的行号和列号用数组全部记录下来了,下面的代码的p和q只能记录最后一个值为0的元素的行号和列号而已
估计所谓的原地算法说的是,不开辟新的内存,直接在原有数据上移动
参考GPT和自己的思路:
原地算法是指在解决问题时,不额外使用存储空间,而是利用原有的存储空间作为算法运算时的临时存储。
第一个代码报错了是因为在函数参数中,二维数组的类型是 int**,而不是 int array[m][n]。因此,需要使用 matrixColSize 数组来获取矩阵的列数。
第二个代码没有使用额外的空间是因为,对于一个 m x n 的矩阵,只需要用两个整数来记录其中一个为 0 的元素所在的行和列。然后再次遍历矩阵,将所在行和列的元素全部设置为 0 即可。因此,不需要使用额外的数组来记录每行、每列是否存在 0 元素。
这段代码的作用是先定义两个大小分别为 m 和 n 的一维数组 row 和 col,然后使用 memset 函数将其全部初始化为 0。这样可以保证在后面记录某个元素所在的行和列时,没有被初始化过的元素也会默认为 0,从而避免无关紧要的干扰。
不知道你这个问题是否已经解决, 如果还没有解决的话:题目要求:
有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数。
写一函数:实现以上功能,在主函数中输入n个数。
例如:
输入:
输入数据的个数n
n个整数
移动的位置m
输出:
移动后的n个数
例如:
输入:
10
1 2 3 4 5 6 7 8 9 10
2
输出:
9 10 1 2 3 4 5 6 7 8
分析:
如何表示要后移的数,
首先,n-m开始取到n为止
其次,从最初取到n-m为止
合起来也就是输出后移的数字串
关键在于将最初的位置(首地址)把握好
#include<stdio.h>
#include<malloc.h>
int main()
{
// 函数声明
void backward(int *q,int *h,int x,int y);
// 定义
int m,n,i;
int *p,*head;
// 输入数据的个数n
scanf("%d",&n);
// 开辟空间存n个数,并保留下首地址
head=p=(int *)malloc(sizeof(int)*n);
// 循环键入
for(i=0;i<n;i++)
{
scanf("%d",p++);
}
// 输入移动的位置m
scanf("%d",&m);
// 调用后移函数
backward(p,head,n,m);
return 0;
}
void backward(int *q,int *h,int x,int y)
{
// 将要后移的y个数先输出
for(q=h+x-y;q<h+n;q++)
{
printf("%d ",*q);
}
// 从头开始输出剩余数
for(q=h;q<h+x-y;q++)
{
printf("%d ",*q);
}
}