You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在循环有序二维数组中实现对数时间复杂度的元素查找

循环有序n阶方阵二分查找实现方案

核心思路

这类循环有序方阵的核心特征是:每次可拆分为4个边长为原边长1/2的同结构子象限,每个子象限的数值范围是连续的且可通过固定位置快速获取最值。每次查找时只需将目标值与4个象限的最值对比,即可确定目标值所在的子象限,将搜索范围直接缩小1/4,每次迭代边长减半,最终时间复杂度稳定为O(log n)。
你现有代码的核心问题在于加入了大量无规律的坐标偏移逻辑,边界判断混乱导致部分场景覆盖不到,只需去掉冗余偏移逻辑,严格按象限范围筛选即可解决。

完整实现代码

public class Circular2DSearch {
    // 测试用例数组
    static int[][] mat = {
            {1, 2, 3, 4, 17, 18, 19, 20},
            {8, 7, 6, 5, 24, 23, 22, 21},
            {12, 11, 10, 9, 28, 27, 26, 25},
            {16, 15, 14, 13, 32, 31, 30, 29},
            {49, 50, 51, 52, 33, 34, 35, 36},
            {56, 55, 54, 53, 40, 39, 38, 37},
            {60, 59, 58, 57, 45, 46, 41, 42},
            {64, 63, 62, 61, 48, 47, 44, 43}};

    public static boolean search(int[][] mat, int target) {
        int n = mat.length;
        // 全局最值判断,提前剪枝
        int globalMin = mat[0][0];
        int globalMax = mat[n-1][0];
        if (target < globalMin || target > globalMax) {
            return false;
        }
        // 当前搜索区域的左上角坐标,初始为(0,0),边长为n
        int startX = 0, startY = 0, size = n;
        while (size >= 1) {
            // 边长为1时直接判断
            if (size == 1) {
                if (mat[startX][startY] == target) {
                    System.out.println("num=" + target);
                    System.out.println("row=" + startX);
                    System.out.println("col=" + startY);
                    return true;
                }
                return false;
            }
            int half = size / 2;
            // 计算四个象限的最值
            int minS1 = mat[startX][startY];
            int maxS1 = mat[startX + half - 1][startY];
            int minS2 = mat[startX][startY + half];
            int maxS2 = mat[startX + half - 1][startY + half];
            int minS3 = mat[startX + half][startY + half];
            int maxS3 = mat[startX + size - 1][startY + half];
            int minS4 = mat[startX + half][startY];
            int maxS4 = mat[startX + size - 1][startY];
            // 判断目标所在象限,切换搜索区域
            if (target >= minS1 && target <= maxS1) {
                // 左上象限,坐标不变,边长减半
                size = half;
            } else if (target >= minS2 && target <= maxS2) {
                // 右上象限,Y轴偏移half
                startY += half;
                size = half;
            } else if (target >= minS3 && target <= maxS3) {
                // 右下象限,X、Y都偏移half
                startX += half;
                startY += half;
                size = half;
            } else if (target >= minS4 && target <= maxS4) {
                // 左下象限,X轴偏移half
                startX += half;
                size = half;
            } else {
                // 不在四个象限范围内,不存在
                return false;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        // 测试用例
        search(mat, 41); // 输出row=6, col=6
        search(mat, 64); // 输出row=7, col=0
        search(mat, 13); // 输出row=3, col=3
        search(mat, 99); // 返回false
    }
}

适配说明

该实现可兼容任意符合该循环有序特性的n阶方阵,无需额外修改逻辑,边长为奇数的场景也可正常适配,每次拆分向下取整即可。

内容的提问来源于stack exchange,提问作者Nadav Avnon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:15:03