剑指Offer----二维数组中的查找(java实现)

 

题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

输入描述

array: 待查找的二维数组 target:查找的数字

输出描述

查找到返回true,查找不到返回false

 

 

package com.xxx;

/**
 * create by ziqiiii
 */
public class Test {

    public static void main(String[] args){
        int target =4;
        int [][]array={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
        System.out.println(Find(target,array));
    }

     static public boolean Find(int target, int [][] array) {
        int row = array.length;
        if(row == 0){
            return false;
        }
        int col = array[0].length;
         if(col == 0){
             return false;
         }
        //方法一:暴力穷举法   时间复杂度:O(n^2)
//        for(int i=0;i<row;i++){
//            for(int j=0;j<col;j++){
//                if(array[i][j]==target){
//                    return true;
//                }
//            }
//        }
//        return false;



         //方法二:找规律:
         //      右上角A:左边的值都比A小,下面的值都比A大
         //      左下角B:上面的值都比B小,右边的值都比B大
         //     所以可以一次性剔除一行或一列
         //     不能选左上角(右、下,都比它大),难以判断走向
         //     也不能选右下角(左、上,都比它小)
         //
         //这里选择右上角开始:  时间复杂度:O(n)
         int aimI=0, aimJ=col-1;
         while(aimI<row && aimJ>=0){
             int aim=array[aimI][aimJ];
             if(aim == target){
                 return true;
             }else if(aim > target){
                 aimJ--;
             }else {
                 aimI++;
             }
         }
         return false;
    }
}

法二:思路:

思路

从数组中选取数字,和目标数字的关系有三种情况:=,<或>。

  1. 如果是等于则查找成功;

  2. 如果是数组中元素小于要查找的数字,说明要查找的数字应该在当前位置的右边或下边。

  3. 如果是数组中元素大于要查找的数字,说明要查找的数字应该在当前位置的左边或上边。

即 对于数组中的任何一个元素, 比它小的元素都在它的左方或者上方, 比它大的元素都在它的右边或者下方

但是这两个区域还有可能有重叠,比如右边或下边会在右下角有重叠。

为了不重复的处理重叠的数据, 我们可以找几个特殊的起点, 比如

起点性质可否作为起点
左上角没有上方元素(小)和左方元素(小)
只有下方元素(大)和右方元素(大)
右上角没有上方元素(小), 和右方元素(大)
只有下方元素(大)和左方元素(小)
左下角没有下方元素(大), 和左方元素(小)
只有上方元素(小)和右方元素(大)
右下角没有下方元素(大), 和右方元素(大)
只有上方元素(小)和左方元素(小)

因此重叠问题的解决方法:

  • 如果查找从右上角开始,如果要查找的数字不在右上角,则每次可以剔除一列或一行。

  • 也可以从左下角开始

  • 但是不能从左上角或者右下角开始。

因为如果选择右上角的元素,

如图,即是我们在二维数组中查找7的轨迹

 

 

法三: 一行一行使用二分查找。

该方法没有方法二快,时间复杂度:O(nlogn)

实现:略

 

 

牛客网运行结果:

 

参考:https://github.com/gatieme/CodingInterviews/tree/master/003-%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9F%A5%E6%89%BE

剑指Offer--题集目录索引

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值