数据结构学习 jz04二维矩阵找数字

题目:

解法一:找角落点,然后渐进目标(像二叉搜索树)

时间复杂度O(n+m)

空间复杂度O(1)

cpp 复制代码
#include <vector>
#include <iostream>
//解法一 找到角落的一个点,然后渐进目标
class Solution {
public:
    bool findTargetIn2DPlants(std::vector<std::vector<int>>& plants, int target) {

        if (plants.size() == 0 || plants[0].size() == 0) return false;//防止是空的
        int m = plants[0].size();
        int n = plants.size();
        for (int x = 0, y = n-1; y >= 0 && x < m;)//从左下角向中心找目标点,要是找出界还没找到就返回false
        {
            if (plants[y][x] == target)//找到啦
                return true;
            else if (plants[y][x] > target)
                y--;
            else
                x++;
        }
        return false;

    }
};

void Test_solution1()
{
    //std::vector<std::vector<int>> x{ {2, 3, 6, 8},{4, 5, 8, 9},{5, 9, 10, 12} };
    std::vector<std::vector<int>> x{ {-5} };
    int target = -2;
    Solution solu;
    std::cout << solu.findTargetIn2DPlants(x, target) << std::endl;
}

解法二:二分查找

在对角线上迭代,对于每一个对角线元素,对该元素所在的行和列使用二分搜索

时间复杂度O(logk!) k=max{m,n}

空间复杂度O(1)

cpp 复制代码
#include <iostream>
#include <vector>
//二分查找
//故意不写成递归是希望多锻炼一下直接写成循环的能力
class Solution {
public:
    bool findTargetIn2DPlants(std::vector<std::vector<int>>& plants, int target) {
        if (plants.empty() || plants[0].empty()) return false;
        int m = plants[0].size()-1;
        int n = plants.size()-1;
        int row = 0;
        int column = 0;
        while (row <= n && column <= m)//在对角线上迭代,对于每一个对角线元素,对该元素所在的行和列使用二分搜索
        {
            //在行上使用二分查找
            int up = row;
            int down = n;
            while (up <= down)
            {
                int mid_row = (up + down) / 2;
                if (plants[mid_row][column] > target)
                {
                    down = mid_row - 1;
                }
                else if (plants[mid_row][column] < target)
                {
                    up = mid_row + 1;
                }
                else
                {
                    return true;
                }
            }
            //在列上使用二分查找
            int left = column;
            int right = m;
            while (left <= right)
            {
                int mid_column = (left + right) / 2;
                if (plants[row][mid_column] > target)
                {
                    right = mid_column - 1;
                }
                else if (plants[row][mid_column] < target)
                {
                    left = mid_column + 1;
                }
                else
                {
                    return true;
                }
            }
            ++row;
            ++column;
        }
        return false;
    }
};

解法三:递归,在列上二分查找,在行上遍历

递归。

在列上用二分法,在行上遍历所有。

  1. 先在mid列上找到plants[row][mid] < target =< lants[row+1][mid]的行row
  2. 然后排除找到的行列的交点的左上(一定比目标小)和右下(一定比目标大)
  3. 接着分成右上和左下,分别调用函数进行递归

时间复杂度O(nlogm)

空间复杂度O(1)

cpp 复制代码
#include <iostream>
#include <vector>
//解法三,递归 在列上用二分法,在行上遍历所有 先在mid列上找到plants[row][mid] < target =< lants[row+1][mid]的行row
//然后排除找到的行列的交点的左上(一定比目标小)和右下(一定比目标大)
//接着分成右上和左下,分别调用函数进行递归
class Solution {
public:
    bool findTargetIn2DPlants(std::vector<std::vector<int>>& plants, int target) {
        if (plants.size() == 0 || plants[0].size() == 0) return false;
        int right = plants[0].size() - 1;
        int down = plants.size() - 1;
        return search_target(plants, target, 0, down, 0, right);
    }
    bool search_target(std::vector<std::vector<int>>& plants, int target, int up, int down, int left, int right)
    {
        if (left > right || up > down) return false;//找不到,超出范围
        
        int mid = (left + right) / 2;//二分 列
        int row = 0;
        while (plants[row][mid] < target && row < down) ++row;//找行
        if (plants[row][mid] == target) return true;//找到了
        //递归
        //后一个row不能是row+1,不然过不了{ {1,3,5} }
        //两边只要有一边找到即可
        return search_target(plants, target, up, row, mid + 1, right) || search_target(plants, target, row, down, left, mid - 1);
    }
};
void Test_solution3()
{
    //std::vector<std::vector<int>> x{ {2, 3, 6, 8},{4, 5, 8, 9},{5, 9, 10, 12} };
    std::vector<std::vector<int>> x{ {1,3,5} };
    int target = 1;
    Solution solu;
    std::cout << solu.findTargetIn2DPlants(x, target) << std::endl;
}

运行结果

二分查找非常快哦。。。。

相关推荐
iqay4 分钟前
【C语言】填空题/程序填空题1
c语言·开发语言·数据结构·c++·算法·c#
字节全栈_kYu22 分钟前
微信小程序视频点播在线视频学习系统 毕业设计 课程设计(1)首页_微信小程序视频功能设计流程图
学习·微信小程序·课程设计
想拿高薪的韭菜32 分钟前
人工智能第2章-知识点与学习笔记
人工智能·笔记·学习
Future_yzx1 小时前
Java Web的发展史与SpringMVC入门学习(SpringMVC框架入门案例)
java·前端·学习
Future_yzx1 小时前
Spring MVC学习——发送请求(@RequestMapping注解及请求参数绑定)
学习·spring·mvc
wen__xvn2 小时前
每日一题洛谷B3865 [GESP202309 二级] 小杨的 X 字矩阵c++
c++·算法·矩阵
LUCIAZZZ2 小时前
Hot100之矩阵
线性代数·矩阵
makabaka_T_T2 小时前
25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表
数据结构·c++·算法·leetcode·链表·矩阵
小菜鸟博士2 小时前
手撕Vision Transformer -- Day1 -- 基础原理
人工智能·深度学习·学习·算法·面试
wclass-zhengge2 小时前
04树 + 堆 + 优先队列 + 图(D1_树(D6_B树(B)))
数据结构·b树