T1-二维数组中的查找

题目描述

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

时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:1539496
本题知识点: 查找、数组

解题思路

本题是二维数组中的查找,刚看到这个题时:

  1. 第一反应就是扒出数组规律:从左到右、从上到下递增;
  2. 接下来无非就是按照数组规律,设定一个查找规则,使算法效率更高;
  3. 这里就有了一个问题:在二维数组遍历时,按照习惯,我们一般会从数组[ 0 ][0]出发,按行列递增的顺序遍历。但是,当我们在遍历数组某个元素a [ i ] [ j ],若目标 target > a [ i ] [ j ],接下来是找a [ i+1 ] [ j ],还是a [ i ] [ j+1]?
  4. (当然这里直接生硬的把整个数组遍历一遍,也是能得到结果的,但是这无疑并不是题目想要的方法)

上述思路问题的关键点就在于,需要找到一种规则使得:当目标 target > a [ i ] [ j ] 或 target < a [ i ] [ j ] 时,算法只有一种遍历方向。

这里,我把数组大致表示了一下:
在这里插入图片描述

不难发现,任意画一条从上到下再从左往右的折线箭头(①、②、③),该箭头所穿过的数组元素都满足递增的顺序,而题目给出的数组便是由许许多多这种所谓的箭头构成。

把箭头的拐点 a [ i ] [ j ]与目标target比较:
若小于目标,则选取a [ i -1] [ j ];
若大于目标,则选取a [ i ] [ j+1 ];
这样,算法的递进过程有了,自然而然,初始时,应该选取数组最左下角的元素参与比较。

把上述过程,直白化描述成算法,就是:初始时,选择数组最左下角的元素,在与目标target比较时,若比target小,则选择该元素右边的元素;若比target大,则选择该元素上面的元素。出界时,算法结束,目标target不在该数组。

时间复杂性:O(n)
最坏情况下时间复杂性:2n

(当然,把上述过程反过来,从数组最右上角的元素开始,也是可行的)

算法描述

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        if(array.size()!= 0)
        {
            int row = array.size()-1;
            int col = 0;//左下角元素坐标
            while(row >= 0 && col < array[0].size() )//数组不越界
            {
                if(array[row][col] == target)
                    return true;//找到
                else if(array[row][col] > target)
                    row--;//目标元素较小,往上找
                else
                    col++;//目标元素较大,往右找
            }           
        }
        return false;  
    }
};

补充:

常见的查找方法

  1. 静态查找:
  • 顺序表的查找:顺序查找、
  • 有序表的查找:折半查找、斐波那契查找、插值查找
  • 静态树表的查找:
  • 索引顺序表的查找:
  1. 动态查找:
  • 二叉排序树和平衡二叉树查找
  • B-树和B+树查找
  • 键树查找
  1. 哈希查找:

常见的排序方法

  1. 插入排序:
  • 直接插入排序
  • 其他插入排序:折半插入、2-路插入、表插入、
  • 希尔排序(缩小增量排序)
  1. 快速排序:
  • 冒泡排序
  1. 选择排序:
  • 简单选择排序
  • 树形选择排序
  • 堆排序
  1. 归并排序:
  2. 基数排序:
  • 多关键字的排序
  • 链式基数排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值