二维数组中的查找

描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。

给定 target = 3,返回 false。

数据范围:矩阵的长宽满足 0≤n,m≤500 , 矩阵中的值满足 0≤val≤10^9

进阶:空间复杂度 O(1) ,时间复杂度 O(n+m)
示例1

输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:true
说明:存在7,返回true  

示例2

输入:1,[[2]]
返回值:false

示例3

输入:3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:false
说明:不存在3,返回false 

代码:
想法。如果target为5,根据递增原则。先从行列下标为0开始,行列计算,当都比5大时,且未找到5,则说明不在该行列。对角找到行列下标为1开始,若对角大于target,则直接返回false;若对角小于target,当行列都比其大时,对角到第三行,则不用继续执行,因下一个对角,一定大于target;当行列都比其小时,重复第一步操作,继续执行下一对角。
在这里插入图片描述

public class Solution {
    public boolean Find(int target, int [][] array) {
        
        if (array.length > 0 && array.length<=500 && array[0].length > 0 && array[0].length<=500){
        int fin = array.length-1;
        
        for(int i = 0  ; i < array.length;i++){
            if(fin < i ){
                    // 对角后面的一定大于target
               return false;
            }
                    // 对角位置
            if(array[i][i] < target){
                        // 执行行列
                for(int j = i ; j<array[i].length;j++){
                    if ((j < array[i].length && array[i][j] > target) && (j<array.length && array[j][i] > target)){
//                         行列皆大于target
                        fin = i;
                        break;
                    }else if ((j < array[i].length && array[i][j] > target) || (j<array.length && array[j][i] > target)){
                        // 判断语句:[1,1]则下标为10没值
                        // 行列有一个大于target
                        if((j < array[i].length && array[i][j] == target) || (j<array.length && array[j][i] == target)){
                            // 可能有一个直接等于target
                            return true;
                        }
                        // 不等于target,且有一个大于,有一个小于,继续执行,可能行列的下一个就是值
                        continue;
                    }else if ((j < array[i].length && array[i][j] == target) || (j<array.length && array[j][i] == target)){
                        // 有一个等于target
                        return true;
                    }else if ((j < array[i].length && array[i][j] < target) || (j<array.length && array[j][i] < target)){
                        // 有一个小于,继续执行
                        continue;
                    }
                }
            }else if(array[i][i] > target){
                fin = i;
                break;
            }else if (array[i][i] == target){
                return true;
            }
        }
        }
        return false;
    }
}

用例通过率:85.71%
写的也是very复杂了,还找不到问题所在。然后发现空间复杂度O(n),时间复杂度O(n^2)
直接暴力法吧。空间复杂度O(n),时间复杂度O(n^2),通过率100%

public boolean Find(int target, int [][] array) {
        
        for(int i = 0 ;i <array.length;i++){
            for (int j = 0; j < array[i].length;j++){
                if(target == array[i][j]){
                    return true;
                }
            }
        }
        return false;
    }

方法:
1、保持一组概念不变
2、取另一组的最大值,当大于该最大值时,则剔除该行或列;小于该最大值时,移动下标。
3、空间复杂度O(1),时间复杂度O(m+n)

public class Solution {
    public boolean Find(int target, int [][] array) {
        
        if(array.length <= 0 || array.length>500 || array[0].length <= 0 || array[0].length>500 ){
            return false;
        }
        
        int row = array.length - 1;
        int col = 0;
        while(row >=0 && col < array[0].length){
            if (array[row][col] > target){
                row--;
            }else if(array[row][col] < target){
                col++;
            }else{
                return true;
            }
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值