每日一算法题-二维数组查找

103 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

一、题目

image.png

#include <vector>
#include <iostream>
using namespace std;

bool find(int target, vector<vector<int> > array) {

}

int main(int, char**)
{
    vector<vector<int> > array = {
            {1,2,8,9},
            {2,4,9,12},
            {4,7,10,13},
            {6,8,11,15}
            };

    cout << (find(7, array) ? "found" : "not found") << endl;

    return 0;
}

二、分析

根据题意可知,需要在二维数组中查询一个节点,
题目规定从左到右,从上到下有序,
有序查找算法通常是用到二分查找,
但是目前是二维数组,中间点就有两个了,
一个是右上,一个是左下,
从哪里走时间复杂度都是相等的,主要看具体查找点更接近哪个中间点了。

由于二维数组不是整体有序,所以不能像二分那样一直跳,
只能通过遍历比较的办法来判断怎么走,
好在有两个方向有序,所以在反方向肯定可以排除,范围就会一直缩小了。

三、模拟

假如从右上开始走:

  1. 9大于7,往左走,这个时候9下面的都比8大,所以往下走也没有意义 [1,2,8,9]
    [2,4,9,12]
    [4,7,10,13]
    [6,8,11,15]

  2. 8大于7,往左走 [1,2,8,9]
    [2,4,9,12]
    [4,7,10,13]
    [6,8,11,15]

  3. 2小于7,往下走 [1,2,8,9]
    [2,4,9,12]
    [4,7,10,13]
    [6,8,11,15]

  4. 4小于7,往下走 [1,2,8,9]
    [2,4,9,12]
    [4,7,10,13]
    [6,8,11,15]

  5. 找到 [1,2,8,9]
    [2,4,9,12]
    [4,7,10,13]
    [6,8,11,15]

四、实现

bool find(int target, vector<vector<int> > array) {
    if(array.empty() || array.at(0).empty()) return false;
    int row = static_cast<int>(array.size()), col = static_cast<int>(array.at(0).size());

    for(int i = 0, j = col - 1; i < row && j >= 0;){
        cout << array[i][j] << endl;
        if(target < array[i][j]){
            --j;
        }else if(target > array[i][j]){
            ++i;
        }else{
            return true;
        }
    }
    return false;
}

五、结言

通常有序查找都是用二分查找算法,但是这里是二维数组,跟二分情况又不一样,具体情况就要具体分析了。

创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!