这在技术上是一个代码挑战。 我在接受采访时被问到一个有趣的问题,我希望得到一些见解,因为我能想到的最好的答案是O(2n ^ 2) - n平方类别,但仍然是相当暴力的。
假设您有一个M大小为N的矩阵(数组数组(int[][]
))
1 2 4 3 1
0 5 3 7 7
5 8 9 2 8
6 7 0 8 9
如果单元格包含零,则将整个行和列设置为零 结果:
0 2 0 3 1
0 0 0 0 0
0 8 0 2 8
0 0 0 0 0
最快和/或最好的方法是什么?
我自己的答案是迭代整个数组,跟踪行和列的归零,然后将它们归零。
public void zeroOut(int[][] myArray){
ArrayList<Integer> rowsToZero = new....
ArrayList<Integer> columnsToZero = new....
for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
for(int j=0; j<myArray[i].length; i++){
if(myArray[i][j] == 0){
if(!rowsToZero.contains(i)) rowsToZero.add(i);
if(!columnsToZero.contains(j)) columnsToZero.add(j);
}
}
}
for(int row : rows){ // now zero the rows
myArray[row] = int[myArray.length];
}
for(int i=0; i<myArray.length; i++){
for(int column: columns){ // now zero the columns
myArray[i][column] = 0;
}
}
}
有更好的算法吗?是否有更好的数据结构来表示这个矩阵?
答案 0 :(得分:1)
你可以通过取两个int
来做到这一点,但唯一的条件是行和列的数量应小于或等于32.您可以使用大于32但是你必须采取的数组整数。
所以逻辑是:
row
和col
matrix[i][j] = 0
,而不是设置row
和col
matrix[i][j] = 0
或row
的相应位,则设置column
。时间复杂度相同 O(N^2)
但内存效率。请在下面找到我的代码。
检查array[row][col] == 0
是否为0而不是设置r
和c
中的相应位。
int r = 0, c = 0;
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 7; col++) {
if (array[row][col] == 0) {
r = r | (1<<row);
c = c | (1<<col);
}
}
}
现在,如果设置了任何一个位,则将单元格设置为0。
for (int row = 0; row < 5; row++) {
for (int col = 0; col <7; col++) {
if (((c&(1<<col))!=0) || ((r&(1<<row))!=0)) {
array[row][col] = 0;
}
}
}
答案 1 :(得分:0)
如何将矩阵分割成相等的较小矩阵部分并计算阻尼剂,以便您可以预测该矩阵部分中存在零。 然后只使用强力机制对这个预先选定的矩阵进行确定 在零行或列中,零是。
决定因素只是一个建议,也许你可以使用其他类型的线性代数 用于预测零值的算法和规则
更新:
如果您使用Quicksort概念来组织每一行的临时性。然后你只需要循环,直到第一个零零元素出现。 您需要在排序过程中记住哪个列索引与0
相关联意味着
1 2 6 0 3
Quciksort(
0 1 2 4 6
当您记住列索引时,您现在可以直接知道要用0填充哪一行以及哪一列
Quicksort的平均值是O(n log n)Worstcase n * n
也许这已经改善了整体的复杂性。
答案 2 :(得分:0)
似乎到目前为止没有人真正想出一个明显更快/更好的算法,所以这个似乎就是这样。感谢大家的投入。
public void zeroOut(int[][] myArray){
ArrayList<Integer> rowsToZero = new....
ArrayList<Integer> columnsToZero = new....
for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
for(int j=0; j<myArray[i].length; i++){
if(myArray[i][j] == 0){
if(!rowsToZero.contains(i)) rowsToZero.add(i);
if(!columnsToZero.contains(j)) columnsToZero.add(j);
}
}
}
for(int row : rows){ // now zero the rows
myArray[row] = int[myArray.length];
}
for(int i=0; i<myArray.length; i++){
for(int column: columns){ // now zero the columns
myArray[i][column] = 0;
}
}
}
答案 3 :(得分:0)
我刚刚遇到了这个问题,并为此开发了一个解决方案。 我希望我可以获得一些关于它是如何更好/更差的代码的反馈,以及它的运行时间。 这一切都很新鲜:)
public static void zeroMatrix(int[][] arr1)
{
ArrayList<Integer> coord = new ArrayList<>();
int row = arr1.length;
int column = arr1[0].length;
for(int i=0; i < row; i++)
{
for(int j=0; j < column; j++)
{
if(arr1[i][j]==0)
{
coord.add((10*i) + j);
}
}
}
for(int n : coord)
{
int j=n%10;
int i=n/10; int k=0;
int l=0;
while(k<row)
{
arr1[k][j]=0;
k++;
}
while(l<column)
{
arr1[i][l]=0;
l++;
}
}
}
答案 4 :(得分:0)
我使用过HashMap。如果这可以以任何方式提供帮助
import java.util.*;
class ZeroMatrix
{
public static void main(String args[])
{
int mat[][]=new int[][]{{0,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,0}};
HashMap<Integer,Integer> ht=new HashMap<Integer,Integer>();
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
if(mat[i][j]==0)
ht.put(i,j);
}
}
//Set the Respected Rows and colums to Zeros
Set set=ht.entrySet();
Iterator itr=set.iterator();
while(itr.hasNext())
{
Map.Entry m=(Map.Entry)itr.next();
int i=(Integer)m.getKey();
int k=(Integer)m.getValue();
for(int j=0;j<4;j++)
{
mat[i][j]=0;
}
for(int j=0;j<5;j++)
{
mat[j][k]=0;
}
}
//Printing the Resultant Zero Matrix
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
System.out.print(mat[i][j]);
}
System.out.println();
}
}
}