【算法练习】剑指offer——有序矩阵查找

思路一:通过mid_i, mid_j, 将矩阵划分为4份,矩阵划分为4份。根据大小情况丢弃左上或者右下角。时间复杂度log(m*n) / log(4/3), m, n为矩阵长宽

#include <iostream>
#include <vector>

using namespace std;
struct point{
    int i, j;
    point(int i, int j) :i(i) ,j(j){}
};

bool f(int target, vector<vector<int> > a, point lu, point rb)
{
    if (lu.i <= rb.i && lu.j <= rb.j){
        int mid_i = (lu.i + rb.i) / 2;
        int mid_j = (lu.j + rb.j) / 2;
        
        if (target == a[mid_i][mid_j]) {
            return true;
        }
        else if (target > a[mid_i][mid_j]){
            return f(target, a, point(lu.i, lu.j + 1), point(mid_i, rb.j))
            || f(target, a, point(mid_i + 1, lu.j), point(rb.i, mid_j))
            || f(target, a, point(mid_i + 1, mid_j + 1), rb);
        }
        else
        {
            return f(target, a, lu, point(mid_i - 1, mid_j - 1))
            || f(target, a, point(mid_i + 1, lu.j), point(rb.i, mid_j))
            || f(target, a, point(lu.i, lu.j + 1), point(mid_i, rb.j));
        }
    }
    return false;
}


bool Find(int target, vector<vector<int> > array) {
    return f(target, array, point(0, 0), point((int)array.size() - 1, (int)array[0].size() - 1));
}


int main()
{
    vector<vector<int> > a;
    int M = 1, N = 5;
    for (int i = 0; i < M; i++)
    {
        vector<int> t;
        for (int j = 0; j < N; j++)
        {
            t.push_back((i * M + j) * 3);
        }
        a.push_back(t);
    }
    
    cout << Find(9, a) << endl;
    
    return 0;
}

思路二, 从左下角开始搜索。时间复杂度m+n

bool Find(int target, vector<vector<int> > array) {
    int i= (int)array.size() - 1,j = 0;
    while(i >= 0 && j < array[0].size()){
        if(target < array[i][j])
            i--; //查找的元素较少,往上找
        else if(target > array[i][j])
            j++; //查找元素较大,往右找
        else
            return true;
    }
    return false;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值