在二维数组中查找非空网格单元

Posted

技术标签:

【中文标题】在二维数组中查找非空网格单元【英文标题】:Finding non-empty grid cell in 2-dimensional array 【发布时间】:2011-09-08 15:52:20 【问题描述】:

我有一个二维整数数组(比如 1000 x 1000),我们称之为矩阵。此矩阵中的每个单元格都有一个 X 坐标和 Y 坐标(在此示例中每个坐标为 0 到 999)。最初所有网格单元的值为 0。在程序运行期间,一些矩阵单元被设置为另一个值 0。

现在我需要一个快速函数(算法),它接受一些 X 和 Y 值并返回该坐标处的矩阵值。但是,如果指定 X/Y 位置的矩阵为 0,则算法应在矩阵内确定一个尽可能接近原始 X/Y 位置的非零值。

我曾考虑在每个循环周期增加偏移量围绕原始 X/Y 位置循环,但我不确定这是否真的是最快的算法...

有什么想法吗?我更喜欢 Java 代码,但任何伪代码也可以:)

提前感谢您的帮助! 亲切的问候,马蒂亚斯

【问题讨论】:

【参考方案1】:

如果数组相对稀疏,并且测试次数相对于插入次数来说很高,那么幼稚的方法可能需要很长时间。

另一种方法是构建空间分区树,例如四叉树或 k-d 树。最近邻搜索是 O(ln N),代价是 O(ln N) 插入时间。

【讨论】:

【参考方案2】:

如果您对矩阵的外观没有任何假设,则必须使用蛮力方法查看 [X, Y] 位置附近的所有值。

    只需将 [X, Y] 位置设置为 3x3 正方形,然后测试正方形周长上的所有值 如果您没有找到非零值,则继续使用正方形 5x5、7x7 等,直到找到。您必须处理大矩阵的边框。

这只是用于循环、索引和适当的 if 的工作 :-) 没有更快的算法,因为您没有任何信息、指南。

【讨论】:

【参考方案3】:

这取决于您希望包含多少行/列包含非 0 值。 如果您希望 1000x1000 的网格填充

如果那不是一个选项,请使用以下内容:

public void foo() 
    int[][]matrix = new int[1000][1000];
    int x = 0,y = 0;
    if(matrix[x][y] != 0) return;
    int min = 0, max=0;
    boolean cont = true;
    foreverloop:
    while(cont) 
        min--;max++;
        for(int ii = min; ii < max; ii++) 
            // secure that min and max dont exeed matrix here.
            cont = false;
            int[] higherEnd = Arrays.copyOf(matrix[ii], max);
            int[] trunk = Arrays.copyOf(higherEnd, higherEnd.length-min);
            Arrays.sort(trunk);
            if(trunk[trunk.length-1] != 0) 
                // HIT! we search this distance but no further.
                trunk = Arrays.copyOf(higherEnd, higherEnd.length-min);
                int source = trunk.length;
                for(int distance = 0; ;distance++) 
                    if(source-distance>0) 
                        if(trunk[source-distance] != 0) 
                            // SCORE!
                            scoreHit(x+ii,y+source-distance);
                            break foreverloop;
                        
                    
                    if(source+distance<trunk.length) 
                        if(trunk[source+distance] != 0) 
                            // SCORE!
                            scoreHit(x+ii,y+source-distance);
                            break foreverloop;
                        
                    
                
            
        
    


public void scoreHit(int x, int y) 
    // there could be several in nearly the same distances

您可以通过过滤掉您已经搜索过的区域来优化它,但我认为这只会在距离 x,y 较远的地方产生影响

【讨论】:

以上是关于在二维数组中查找非空网格单元的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer(Java)-1-二维数组中的查找

在 nxn 的二维数组中查找局部最大值

二维数组中所有岛屿之间的最大总和是多少?必须使用递归

在二维块网格中查找矩形

C++中如何在一个二维数组中查找某个值

二维数组的查找