小时候玩炸弹人的游戏咱们都知道,你扔一个炸弹出去它会形成十字火焰,然后等你威力提高之后,整个一行和一列都是火焰。因此我现在把这个算法就叫做炸弹人问题。
这是提出问题的贴子:点击打开链接
里面有很多人提出下面的算法。整个算法思想很简单。
事先约定好一个肯定不会在数组中出现的数。我称之为K。
逐行遍历每一个元素,如果遇到零元,则将整行非零元都变为K后遍历下一行。这种行为我称为K化。
以同样的方式遍历每一列。
最后遍历整个数组,将值为K的元素置为0
void ArraySetToZero(int pArray[3][4],int nRows,int nCols) //由于是测试代码,因为二维数组暂定为3×4的
{
BOOL bHasZero = FALSE;
//第一轮。逐行查找零元
for(int i = 0;i<nRows;i++)
{
bHasZero = FALSE;
for(int j = 0;j<nCols;j++)
{
if(pArray[i][j] == 0)
{
bHasZero = TRUE;//本行需要K化。
break;
}
}
if (bHasZero)
{
//K化
for(int j = 0;j<nCols;j++)
{
{if(pArray[i][j] != 0) pArray[i][j] = NONE_EXIST_ELEMENT;}; //K化正行元素
}
}
}//O(N*M)
//第二轮。逐列查找零元
for(int j = 0;j<nCols;j++)
{
bHasZero = FALSE;
for(int i = 0;i<nRows;i++)
{
if(pArray[i][j] == 0)
{
bHasZero = TRUE;//本行需要K化。
break;
}
}
if (bHasZero)
{
//K化
for(int i = 0;i<nRows;i++)
{
{if(pArray[i][j] != 0) pArray[i][j] = NONE_EXIST_ELEMENT;}; //K化正行元素
}
}
}
//最后一轮,把K变成0
for(int i = 0;i<nRows;i++)
{
for(int j = 0;j<nCols;j++)
{if(pArray[i][j] == NONE_EXIST_ELEMENT) pArray[i][j] = 0;}
}
}