剑指 Offer 04. 二维数组中的查找

剑指 Offer 04. 二维数组中的查找

题目描述

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

在这里插入图片描述

方法一

解题思路

对每一行进行二分查找

代码
class Solution {
    /**
    方法1:
        对每一行或列采用二分查找
            优化:当某行最小元素大于target时,直接排除
    
     */

     
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        int n = matrix.length;  //行数
        if(n == 0){
            return false;
        }
        int m = matrix[0].length;  //列数
        if(m == 0){
            return false;
        }

        for(int i = 0;i<n;i++){
            if(matrix[i][0] > target){
                continue;
            }else{
                if(binarySearch(matrix[i],target)){
                    return true;
                }
            }
        }

        return false;

    }
    public boolean binarySearch(int[] nums,int target){
        int low,mid,high;
        low = 0;
        high = nums.length - 1;
        
        while(low <= high){
            mid = (low + high)/2;
            if(nums[mid] == target){
                return true;
            }
            if(target > nums[mid]){
                low = mid + 1;
            }
            if(target < nums[mid]){
                high = mid - 1;
            }
        }

        return false;

    }



}

方法二

解题思路

我们将矩阵逆时针旋转45度,并将其转换为图形式,发现其类似于二叉搜索树,即对于每个元素,其左分支元素更小、右分支元素更大。因此,通过从”根节点“开始搜索,遇到比target大的元素就向左,反之向右,即可找到目标值target。
在这里插入图片描述
”根节点“对应的是矩阵的”左下角“和”右上角“元素,本文称之为标志数,以matrix中的左下角元素为标志数flag,则有:
1、若flag > target,则target一定在flag所在行的上方,即flag所在行可被消去。
2、若flag < target,则target一定在flag所在列的右方,即flag所在列可被消去。

算法流程

1、从矩阵martix左下角元素(索引设为(i,j))开始遍历,并于目标值对比
当martix[i][j] > target 时,执行i–,即消去第 i 行元素
当martix[i][j] < target 时,执行j++,即消去第 j 列元素
当martix[i][j] == target 时,返回true,代表找到目标值
2、若行索引或列索引越界,则代表矩阵中无目标值,返回false

代码
class Solution {
    

    /**
    方法2:标志数法
        ”根节点“对应的是矩阵的”左下角“和”右上角“元素,本文称之为**标志数**,以matrix中的左下角元素为标志数flag,则有:
	1、若flag > target,则target一定在flag所在**行的上方**,即flag所在行可被消去。
	2、若flag < target,则target一定在flag所在**列的右方**,即flag所在列可被消去。
    
     */

    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if(matrix.length == 0){
            return false;
        }

        if(matrix[0].length == 0){
            return false;
        }

        int i = matrix.length - 1;
        
        int j = 0;
        while(i >= 0 && j < matrix[0].length){
            //System.out.println(i+ "and" +j);
            if(matrix[i][j] == target){
                return true;
            }else if(matrix[i][j] < target){
                j++;
            }else if(matrix[i][j] > target){
                i--;
            }
        }

        return false;

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值