二维数组中的查找


题目地址

尝试一

尝试一是不通过的,因为我以为将二维数组转换为一维数组是顺序递增的(如:int a[][]={{1,2,3},{4,7,8},{10,14,15}}),所以我就想把二维数组转换为一维数组,利用二分查找来查询target。然而,事实不是这样(如:[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]])。

public class Solution {
    private static int[][] a;
    private static int t;
    public boolean Find(int target, int [][] array) {
        /*将参数存在实例变量,便于使用*/
        a=array;
        t=target;
      /*二分查找法查询0~m*n */
        int l=0;
        int m=array.length;
        int n=array[0].length;
        int r=m*n-1;
        boolean result=binarySearch(l,r);
        return result;
        
    }
    
    public static boolean binarySearch(int l,int r){
        if((l+1)==r){
            if(t==find(l)|| t==find(r)){
                return true;
            }
            return false;
        }
        int i=(l+r)/2;
         
        if(find(i)==t){
            return true;
        }else if(t>find(i)){
            return binarySearch(i,r);
        }else{
            return binarySearch(l,i);
        }
    }
    
    public static int find(int i){
        /*获取二维数组的行数和列数*/
        int n=a[0].length;
          //行
        int x=i/n;
        //列
        int y=i%n;
        return a[x][y];
    }
    
}

尝试二

失败。我错误的以为target一定存在于第一个array[i][0]<target<array[i][array[0].length]。

public class Solution {
    private static int[][] a;
    private static int t;
    public boolean Find(int target, int [][] array) {
        /*将参数存在实例变量,便于使用*/
        a=array;
        t=target;
      /*先确定行*/
        int i=-1;
        for(int row=0;row<a.length;++row){
            if(t>=a[row][0] &&t<=a[row][a[row].length]){
                i=row;
            }
        }
        
        /*没找到行,直接返回*/
        if(i==-1){
            return false;
        }
        
        /*确定列,在列上进行二分查找*/
        boolean result= binarySearch(0, a[i].length,a[i]);
        return result;
       
        
    }
    
    public static boolean binarySearch(int l,int r,int[] array ){
        if((l+1)==r){
            if(t==array[l]||t==array[r]){
                return true;
            }else{
                return false;
            }
        }
        int m=(l+r)/2;
        if(array[m]==t){
            return true;
        }
        else if(array[m]>t){
            return binarySearch(l,m,array);
        }else{
            return binarySearch(m,r,array);
        }
        
    }
    
    
    
}

尝试三

既然target不一定一定存在于第一个array[i][0]<target<array[i][array[0].length]。那我就将每一个满足array[i][0]<target<array[i][array[0].length]的行都进行二分查找

public class Solution {
    private static int[][] a;
    private static int t;
    public boolean Find(int target, int [][] array) {
        /*将参数存在实例变量,便于使用*/
        a=array;
        t=target;
      /*先确定行*/
        for(int row=0;row<a.length;++row){
            /*考虑到{{}}这种情况*/
            if(a[row].length==0){
                return false;
            }
            
            if(t>=a[row][0] &&t<=a[row][a[row].length-1]){
                /*确定列,在列上进行二分查找*/
                boolean result= binarySearch(0, a[row].length-1,a[row]);
                /*result==true,说明已经找到了*/
                if(result==true){
                    return true;
                }
                
                //否则继续
                
            }
        }
        
        /*遍历了每一行都没找到,才返回false*/
        return false;
        
      
       
        
    }
    
    public static boolean binarySearch(int l,int r,int[] array ){
        if((l+1)==r){
            if(t==array[l]||t==array[r]){
                return true;
            }else{
                return false;
            }
        }
        int m=(l+r)/2;
        if(array[m]==t){
            return true;
        }
        else if(array[m]>t){
            return binarySearch(l,m,array);
        }else{
            return binarySearch(m,r,array);
        }
        
    }
    
    
    
}

需要注意的是:要考虑到{{}}这种情况。

结论

二分查找,要注意当l+1==r时这种情况,不然你只考虑l==r的情况的话,容易产生死循环,如:
(3+4)/2=3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值