Java版牛客网剑指offer编程题第1题--二维数组中的查找

        跟learnjiawa一起每天一道算法编程题,既可以增强对常用API的熟悉能力,也能增强自己的编程能力和解决问题的能力,算法和数据结构,是基础中的基础,更是笔试的重中之重。

  • 不积硅步,无以至千里;
  • 不积小流,无以成江海。

题目描述

牛客网剑指offer编程题no1
牛客网剑指offer编程题第1题–二维数组中的查找,在一个二位数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

解题方法1

   /**
     * 思路就是折半查找,因为数组是有序的,所以可以减少查找次数,
     * 不用一个个暴力地取去比较
     * */
    public static boolean find(int target, int [][] array) {

        int length = array[0].length - 1;
        for(int i=0; i < array.length; i++){
            //将二维数组分解成数个一维数组,逐个查找
            int leftindex = 0;
            int rightindex = length;
            while(leftindex < rightindex -1){
                //如果和两个边界值相等,就直接返回true
                if(array[i][leftindex] == target || array[i][rightindex] == target){
                    return true;
                }
                int rowmid = array[i][(leftindex+rightindex)/2];
                if(target == rowmid){
                    return true;
                }else if(target > rowmid){
                    leftindex = (leftindex+rightindex)/2;
                }else if(target < rowmid){
                    rightindex = (leftindex+rightindex)/2;
                }
            }
        }
        return false;

    }

解题方法2

    /* 思路
     * 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增,
     * 因此从左下角开始查找,当要查找数字比左下角数字大时。右移
     * 要查找数字比左下角数字小时,上移,例如
		{1,2,8,9},
		{2,4,9,12},
		{4,7,10,13},
		{6,8,11,15}
     */

    public static boolean find2(int target, int [][] array) {
        int rowCount = array.length;
        int colCount = array[0].length;
        int i,j;
        for(i=rowCount-1,j=0; i>=0 && j<colCount;)
        {
            if(target == array[i][j])
                return true;
            if(target < array[i][j])
            {
                i--;
                continue;
            }
            if(target > array[i][j])
            {
                j++;
            }
        }
        return false;
    }

代码测试

package com.learnjiawa.jzoffer;

/**
 * @author zouhuayu
 * 2019-11-30-11:21
 */
public class Solution1 {
    /**
     * 思路就是折半查找,因为数组是有序的,所以可以减少查找次数,不用一个个暴力地取去比较
     * */
    public static boolean find(int target, int [][] array) {

        int length = array[0].length - 1;
        for(int i=0; i < array.length; i++){
            //将二维数组分解成数个一维数组,逐个查找
            int leftindex = 0;
            int rightindex = length;
            while(leftindex < rightindex -1){
                //如果和两个边界值相等,就直接返回true
                if(array[i][leftindex] == target || array[i][rightindex] == target){
                    return true;
                }
                int rowmid = array[i][(leftindex+rightindex)/2];
                if(target == rowmid){
                    return true;
                }else if(target > rowmid){
                    leftindex = (leftindex+rightindex)/2;
                }else if(target < rowmid){
                    rightindex = (leftindex+rightindex)/2;
                }
            }
        }
        return false;

    }

    /* 思路
     * 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增,
     * 因此从左下角开始查找,当要查找数字比左下角数字大时。右移
     * 要查找数字比左下角数字小时,上移
     */

    public static boolean find2(int target, int [][] array) {
        int rowCount = array.length;
        int colCount = array[0].length;
        int i,j;
        for(i=rowCount-1,j=0; i>=0 && j<colCount;)
        {
            if(target == array[i][j])
                return true;
            if(target < array[i][j])
            {
                i--;
                continue;
            }
            if(target > array[i][j])
            {
                j++;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int target = 1;

        int[][] array = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};

        System.out.println(find2(target, array));

    }
}

总结

从巧妙地角度来说,第二种方法显然是更胜一筹的,它充分利用了提给条件中地二维素组每一列每一行都是有序地这个条件。不过第一种解题思路显然是更加容易想到的,存在的一个小问题是,它只利用了每一个一维数组,也就是每一行的元素是有序的这一个条件,而没有利用每个一维数组的首位元素也是有序的这个条件,所以还是存在着一定的优化空间,不过这两种解题思路都是满足解题限制的,比暴力解法好了很多。

参考文献

[1]程杰. 大话数据结构. 北京:清华大学出版社, 2011.

更多

对我的文章感兴趣,持续更新中…
关注我,看其他系列博客,《跟凑弟弟一起修炼集合框架》、《Java多线程大闯关》、《Java IO流大闯关》。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值