二维数组中的查找(一层循环)

题目描述https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof

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

示例:

现有矩阵 matrix 如下:

[

[1, 4, 7, 11, 15],

[2, 5, 8, 12, 19],

[3, 6, 9, 16, 22],

[10, 13, 14, 17, 24],

[18, 21, 23, 26, 30]

]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

思路

想法一

直接使用两层for循环遍历数组,逐个对比是否等于目标值,若找到返回true,没找到返回false

想法二

由于数组从左到右,从上到下是非递减排序的,因此可以参考二分法,选取中间值,若大于则在该值的右边列和下边行,小于则在左边列和上面行,但会使待搜索行列有重复搜索的区域

想法三

既然是非递减序列,则可以选取行数最小列数最大所对应的值,即右上角,若小于右上角则缩减一列,所大于右上角则下移一行,达到无重复搜索的地方

同理左下角也成立

但左上角和右下角不成立

从右上角开始缩小范围——完整代码如下(ACM模式)
#include<iostream>
#include<vector>
using namespace std; 


class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0 || matrix[0].size()==0){
            return false;
        }

        int row=0;
        //记录列数
        int column=matrix[0].size()-1;

        //每次选取右上角的点,若小于右上角则缩减一列,所大于右上角则下移一行
        while(row<matrix.size() && column>=0){
            int m=matrix[row][column];
            if(target<m){
                column--;//左移一列
            }else if(target>m){
                row++;//下移一行
            }else{
                return true;
            }
        }
        return false;//没找到
    }
};

int main(){
    int h,l;
    cin>>h>>l;
    int target;
    cin>>target;
    
    //vector创建二维数组,并全部初始化为1
    vector<vector<int>> matrix(h,vector<int>(l,1));
    for(int i=0;i<h;i++){
        for(int j=0;j<l;j++){
            cin>>matrix[i][j];
        }
    }
    
    Solution solution;
    bool result=solution.findNumberIn2DArray(matrix,target);
    cout<<"result:"<<result;
}

扩展

二维vector的初始化https://blog.csdn.net/Echo1214_Xie/article/details/81208449

先初始化第一维,才可加入元素

vector<vector<int>> matrix(h,vector<int>(l,1));
for(int i=0;i<h;i++){
    for(int j=0;j<l;j++){
        cin>>matrix[i][j];
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值