java 矩阵查找

  //忽略代码风格...大小写比较随意了  
  private static final int[][] matrix = {
            {1, 2, 4, 5, 6, 7},
            {3, 4, 7, 8, 9, 10},
            {4, 5, 8, 12, 14, 16},
            {4, 6, 9, 14, 15, 17},
    };

    /**
     * 在二维数组中查找某个数是否存在
     * 次二维数组横向与纵向都是单调递增的
     */
    public static boolean testFindValueInMatrix01(int[][] matrix, int key) {
        Log.i("testFindValueInMatrix", "testFindValueInMatrix01 key=" + key);
        int rowCount = matrix.length;
        int columnCount = matrix[0].length;
        if (key < matrix[0][0]) {
            return false;
        } else if (key > matrix[matrix.length - 1][matrix[0].length - 1]) {
            return false;
        } else {
            for (int i = 0; i < rowCount; i++) {
                Log.i("testFindValueInMatrix", "testFindValueInMatrix01 i=" + i);
                if (key > matrix[i][columnCount - 1] || key < matrix[i][0]) {
                    Log.i("testFindValueInMatrix", "testFindValueInMatrix01 continue");
                    continue;
                } else {
                    for (int j = columnCount - 1; j >= 0; j--) {
                        if (key == matrix[i][j]) {
                            Log.i("testFindValueInMatrix", "testFindValueInMatrix01 find it "+"("+i+","+j+")");
                            return true;
                        }
                    }
                }

            }
        }
        return false;
    }
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 key=14
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=0
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 continue
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=1
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 continue
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=2
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 find it (2,4)
思路:

1.先与左上角的数字and 右下角的数字 对比,如果不在范围内直接false;

2.与第一行最左 and最右的数字对比,不在范围内,直接continue换下一行;

3.如果‘可能’在行内,那么遍历这一行;

4.如果不在行内,进行下一行的遍历;


ps:还有更好的方式,待续

方法2:

public static boolean testFindValueInMatrix03(int[][] matrix,int key){
        int i = 0, j = matrix[0].length - 1;
        int var = matrix[i][j];
        while (i < matrix.length && j >= 0){
            if (var == key) {
                Log.i("testFindValueInMatrix", "testFindValueInMatrix03 find it " + "(" + i + "," + j + ")");
                return true;
            }else if (var < key) {
                var = matrix[++i][j];
            }else {
                var = matrix[i][--j];
            }
        }
        return false;
    }

网上有人叫上面这个方法是‘定位法’,这个方法其实是前一个方法的变种,从右上角那个数开始比较,如果右上角的数比key大,那么就向左走,如果右上角的数比key小,就向下走;拿14为例,右上角的数比14小,所以一路向下走到第三行,16比14大,想走走,14刚好找到。

方法3:

采用递归+二分法 的方式。

public static boolean testFindValueInMatrix02(
            int left,
            int right,
            int top,
            int bottom,
            int[][] matrix,
            int key) {
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 key=" + key);
        int midCol =  (left+right)>>1;
        int midRow =  (top+bottom)>>1;
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 left="+left+
                "--right="+right+
                "--top="+top+
                "--bottom="+bottom+
                "--midCol="+midCol+
                "--midRow="+midRow);
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 midValue=" + matrix[midRow][midCol]);
        if(left>right || top>bottom || midCol > right || midRow > bottom){
            return false;
        }
        if(key > matrix[bottom][right]){
            return false;
        }else if(key < matrix[top][left]){
            return false;
        }else{

            if(key>matrix[midRow][midCol]){
                return testFindValueInMatrix02(
                        midCol+1,
                         right,
                        midRow+1,
                        bottom,
                        matrix,
                        key) ||
                        testFindValueInMatrix02(
                                midCol+1,
                                right,
                                top,
                                midRow,
                                matrix,
                                key) ||
                        testFindValueInMatrix02(
                                left,
                                midCol,
                                midRow+1,
                                top+bottom,
                                matrix,
                                key);
            }else if (key<matrix[midRow][midCol]){
                return testFindValueInMatrix02(
                        left,
                        midCol-1,
                        top,
                        midRow-1,
                        matrix,
                        key) ||
                        testFindValueInMatrix02(
                                midCol,
                                right,
                                top,
                                midRow-1,
                                matrix,
                                key) ||
                        testFindValueInMatrix02(
                                left,
                                midCol-1,
                                midRow,
                                bottom,
                                matrix,
                                key);
            }else{
                Log.i("testFindValueInMatrix", "testFindValueInMatrix02 find it "+"("+(midRow)+","+(midCol)+")");
                return true;
            }
        }
    }

这个方法我简单测试,是没问题的。思路就是:根据二分法查看key在哪个区域,然后在那个区域回调查找,如图:



例如第一个mid位置的值是7,查找14,14>7,那么就在A,B,C三个区域再次查找。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中有向图的邻接矩阵是一种常见的数据结构,用于表示有向图的连接关系。邻接矩阵是一个二维数组,行列分别对应图中的顶点。 在有向图的邻接矩阵中,矩阵的行和列分别代表图中的顶点。如果有向图中存在一条从顶点i到顶点j的有向边,那么对应的邻接矩阵中第i行第j列的元素设为1;否则,设为0。如果有多条边连接同一个顶点,也只需要在对应的位置设置为1即可,不需要额外的信息记录。 邻接矩阵具有以下优点: 1. 查找两个顶点之间是否有边的连接非常高效,只需要在邻接矩阵中对应的位置查找即可。 2. 判断某个顶点的出度和入度也非常方便,只需要统计矩阵中对应行或列中1的数量即可。 3. 适用于表示稠密图,即顶点较多且边数较多的图。 然而,邻接矩阵也存在一些限制和缺点: 1. 占用的空间较大,矩阵的大小为顶点数的平方,即使图中的边比较稀疏,仍然需要占用较多的空间。 2. 对于表示稀疏图,即顶点较多但边数相对较少的图,邻接矩阵的空间利用率较低。 3. 插入和删除边的操作较为耗时,需要修改多个位置的元素。 综上所述,有向图的邻接矩阵是一种常见且实用的表示方法,尤其适用于稠密图的表示和高效的访问操作。但对于稀疏图,或需要频繁插入和删除边的操作,可能更适合使用其他的图的表示方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值