Java 使用O(n)时间复杂度搜索返回true到给定方法的二维数组';这是一个陷阱

Java 使用O(n)时间复杂度搜索返回true到给定方法的二维数组';这是一个陷阱,java,arrays,algorithm,search,time-complexity,Java,Arrays,Algorithm,Search,Time Complexity,所以我需要一个java方法,它接收一个二维整数数组和一个整数,并在数组中查找整数。如果找到,将返回true;否则就错了但时间复杂度为O(n) 这里有一个问题,我们还知道传递到我们方法中的二维数组返回true到以下方法: public static boolean test(int [][] m) { int n=m.length; for(int r=0; r<(n-1); r++) for (int c=0; c<n; c++) for (int i=

所以我需要一个java方法,它接收一个二维整数数组和一个整数,并在数组中查找整数。如果找到,将返回true;否则就错了但时间复杂度为O(n)

这里有一个问题,我们还知道传递到我们方法中的二维数组返回true到以下方法:

  public static boolean test(int [][] m)
{
 int n=m.length;
 for(int r=0; r<(n-1); r++)
    for (int c=0; c<n; c++)
       for (int i=0; i<n; i++)
          if(m[r][c] > m[r+1][i]) return false;
return true;
}
添加findValTest方法的API文档

/**
     * Checks if a given value exists in a given array; While it is known that given the method test returns true for the given array
     * @param m the array to check
     * @param val the value to find
     * @return true if val is found in the array; false otherwise.
     * @timeComplexity O(n) n- the array's (m) length
     * @spaceComplexity O(1)
     */
这里的关键是找到一个时间复杂度为O(n)的算法,该算法可以根据我们从方法测试中了解的内容来找到值

这是我的方法,它不工作,你

public static boolean findValTest(int[][] m, int val) {
        int index = 0;
        while(index < m.length) {
            if(m[index][0] < val)
                index++;
            else
                break;
        }

        for(int index2 = 0; index2 < m[0].length; index2++) {
            if(m[index][index2] == val)
                return true;
        }
        return false;
    }
公共静态布尔findValTest(int[][]m,int val){
int指数=0;
而(指数

我很确定它不是偶数O(n),而是O(n^2).

您的解决方案的问题是数字可以是两行中的任意一行。假设您正在查找
41
——您的第一个循环将选择
index=4
(以60开头的行),但
41
位于前一行。但是,如果您正在搜索
53
,您的方法将正确返回true

public static boolean findValTest(int[][] array, int val) {
    int chosenRow = 0;
    while (chosenRow < array.length) {
        if (array[chosenRow][0] < val) {
            chosenRow++;
        } else {
            break;
        }
    }

    for (int row = min(chosenRow, array[0].length - 1); row >= max(chosenRow - 1, 0); row--) { // max 2 iterations - chosen row, and row before
        for (int col = 0; col < array[0].length; col++) {
            if (array[row][col] == val) {
                return true;
            }
        }
    }
    return false;
}
公共静态布尔findValTest(int[][]数组,int val){
int chosenRow=0;
while(chosenRow=max(chosenRow-1,0);row--){//max 2次迭代-所选行和之前的行
for(int col=0;col
我们需要执行
min
,因为
chosenRow
可能超过数组大小,例如查找147。我们需要检查
max
,以防
chosenRow
为0,例如在查找0时


实际上,复制粘贴内部循环并将它们都放在if语句下可能比执行外部循环更漂亮。

Smth。像那样。如果行
i
上的每个数字等于或小于行
i+1
上的每个数字,则您只能检查每行中的第一个元素来定义一行,其中所需的值可以是。未排序行中的元素只能通过完全扫描找到

此算法必须只扫描2整行,即O(n),其中n-行数

public static boolean findValTest(int[][] m, int val) {
    for (int row = 0; row < m.length; row++) {
        if (m[row][0] <= val && row != m.length - 1)
            continue;

        int r = row;

        while (r >= row - 1 && r >= 0) {
            for (int col = 0; col < m[r].length; col++)
                if (m[r][col] == val)
                    return true;

            r--;
        }

        return false;
    }

    return false;
}

所以每一列都被排序了,对吗?然后在任意一列上进行二进制搜索,找到最接近的值
sebrockm,嗯,不,我想这样就可以了。我会去写的,谢谢@我想不会的。比如说,我们正在寻找
5
,排序后您可以看到
4
6
5
可以在两行中的任何一行中。@解决方案的问题是,数字可以在两行中的任何一行中。假设您正在查找
41
——您的第一个循环将选择
index=4
(以
60
开头的行),但
41
位于前一行。但是,如果您正在搜索
53
,您的方法将正确返回
true
@shadow重载不要不断更改您发布的原始代码-这样做会使所有注释和答案变得无关,因为它们引用的是不再存在的代码。我刚刚更新了我的解决方案,线程“main”java.lang.ArrayIndexOutOfBoundsException:8在Ex14.findValTest(Ex14.java:80)在Test14.main(Test14.java:95)中仍然不工作异常当我查找数字136时,是的,我在示例中传递数组,数字是:0、1、2、5、7、21、23、41、42、47、51、52、53、56、57、58、60、61、65、70,72、73、78、82、98、100、111、112、121、123、134、136、147、150、154要查找,它会在线程“main”java.lang.ArrayIndexOutOfBoundsException:8在Ex14.findValTest(Ex14.java:64)在Test14.main(Test14.java:95)上发送此消息@ShadowOverLoad不,我现在看到了!谢谢,你的解决方案非常聪明!
public static boolean findValTest(int[][] array, int val) {
    int chosenRow = 0;
    while (chosenRow < array.length) {
        if (array[chosenRow][0] < val) {
            chosenRow++;
        } else {
            break;
        }
    }

    for (int row = min(chosenRow, array[0].length - 1); row >= max(chosenRow - 1, 0); row--) { // max 2 iterations - chosen row, and row before
        for (int col = 0; col < array[0].length; col++) {
            if (array[row][col] == val) {
                return true;
            }
        }
    }
    return false;
}
public static boolean findValTest(int[][] m, int val) {
    for (int row = 0; row < m.length; row++) {
        if (m[row][0] <= val && row != m.length - 1)
            continue;

        int r = row;

        while (r >= row - 1 && r >= 0) {
            for (int col = 0; col < m[r].length; col++)
                if (m[r][col] == val)
                    return true;

            r--;
        }

        return false;
    }

    return false;
}
System.out.println(findValTest(arr3, -1)); // false
System.out.println(findValTest(arr3, 5)); // true
System.out.println(findValTest(arr3, 7)); // true
System.out.println(findValTest(arr3, 55)); // false
System.out.println(findValTest(arr3, 47)); // true
System.out.println(findValTest(arr3, 147)); // true
System.out.println(findValTest(arr3, 200)); // false
System.out.println(findValTest(new int[][] { { 3, 4, 5 } }, 4));   // true