[剑指offer_04] 二维数组中查找目标值

本文介绍在二维数组中查找目标值的几种高效算法,包括从右上角或左下角开始的双指针法,以及逐行遍历结合二分查找的方法,通过具体实现和测试用例,展示了不同算法的时间复杂度和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[剑指offer_04] 二维数组中查找目标值

1. 二维数组中查找目标值

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

思路:从右上角或左下角开始找,逐行排除,或者用逐行遍历+二分法查找

2. 右上角开始找

    /**
     * 解法一:双指针(右上方开始找)
     * 时间复杂度:O(m*n),空间复杂度:O(1)
     *
     * @param array 二维数组
     * @param target 目标值
     * @return true:找到  false:未找到
     */
public boolean Find1(int target, int [][] array) {  
    if(array == null && array.length == 0){
        return false;
    }
    int row = 0; //行
    int col = array[0].length - 1; //列

    while(row < array.length && col >= 0) {
        if(array[row][col] == target) {//如果刚好等于target,返回true
            return true;
        } 
        if(array[row][col] > target) {//如果该数字大于target,剔除所在列
            col --; //列左移
        }else{ //如果小于target,剔除所在行
            row ++; //行下移
        }
    }
    return false;
}
    

3. 左下角开始找

/**
 * 解法一:双指针(左下方开始找)
 * 时间复杂度:O(mn),空间复杂度:O(1)
 *
 * @param array 二维数组
 * @param target 目标值
 * @return true:找到  false:未找到
 */
public static boolean find2(int[][] array, int target) {
    if (array == null || array.length == 0) {
        return false;
    }
    int row = array.length - 1; //行
    int column = 0; //列

    while (row >= 0 && column < array[0].length) {
        if (array[row][column] == target) {//如果刚好等于target,返回true
            return true;
        }
        if (array[row][column] > target) {
            row--; //行,目标小于当前值,往上找
        } else {
            column++; //列,目标比当前值大,往右边找
        }
    }
    return false;
}

4. 逐行遍历+二分查找

/**
 * 解法二:二分法
 * 时间复杂度:O(log m*n),空间复杂度:O(1)
 *
 * @param array 二维数组
 * @param target 目标值
 * @return true:找到  false:未找到
 */
public static boolean find3(int[][] array, int target) {
    //非空判断
    if(array == null || array.length == 0){
        return false;
    }
    for(int i = 0; i< array.length; i++) {
        int left = 0;
        int right = array[0].length - 1; //不要忘记减去1
		//二分查找
        while(left<=right) {
            int mid = (left + right) / 2;
            if(target == array[i][mid]){
                return true;
            }else if(target > array[i][mid]){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
    }
    return false;
}

5. 测试用例

/**
 * 测试Test3
 *
 * @author 周鹏飞
 * @version 1.0
 * @date 2020/3/28 15:10
 */
public class Test3 {

    @Test
    public void test3() {
        int[][] testArray = {{1, 7, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        int target = 1;//1,6,15
        System.out.println("解法一:两个指针(右上),数组中是否含有" + target + " :" + FindNum3.find(testArray, target));
        System.out.println("解法一:两个指针(左下),数组中是否含有" + target + " :" + FindNum3.find2(testArray, target));
        System.out.println("解法二:二分法,数组中是否含有" + target + " :" + FindNum3.find3(testArray, target));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值