【剑指Offer】个人学习笔记_ 04_ 二维数组中的查找

目录

    • 初始解答:
    • 学习他人:
      • 方法一:
      • 自己尝试
      • 方法二:
      • 方法三:
    • 再改方法一
    • 教材示例代码
    • 总结

刷题日期:18:5814 星期四2021年3月11日

个人刷题记录,代码收集,来源皆为leetcode

主要答题语言为C++

初始解答:

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        bool found = false;
        if(matrix.size()>0 && matrix[0].size()>0)  //insure
        {
            int row=0;
            int column = matrix.size()-1;
            while(row<matrix.size() && column >0){
                if(matrix[row][column]=target){
                    found = true;
                    break;
                }
                else if (matrix[row][column]>target)
                    column--;
                else
                    row++;
            }
        }
        return found;
    }
    
}

基础不扎实,老是报错:
【剑指Offer】个人学习笔记_ 04_ 二维数组中的查找_第1张图片

问题为判断语句为==,而代码中写成了=,表示赋值,最后23行大括号闭后的分号也被删除了,修改后的代码为

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        bool found = false;
        if(matrix.size()>0 && matrix[0].size()>0)  //insure
        {
            int row = 0;
            int column = matrix.size() - 1;
            while(row < matrix[0].size() && column >= 0){
                if(matrix[row][column] == target){
                    found = true;
                    break;
                }
                else if(matrix[row][column] > target)
                    column--;
                else
                    row++;
            }
        }
        return found;
    }
    
};

提交还是没有通过,具体的报错也看不太懂,显示一串地址错误,使用了下面提供的方法1

学习他人:

作者:jyd
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/mian-shi-ti-04-er-wei-shu-zu-zhong-de-cha-zhao-zuo/
来源:力扣(LeetCode)

方法一:

思路相同,代码更简洁


class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int i = matrix.size() - 1, j = 0;
        while(i >= 0 && j < matrix[0].size())
        {
            if(matrix[i][j] > target) i--;
            else if(matrix[i][j] < target) j++;
            else return true;
        }
        return false;
    }
};

是有些取巧的,没有考虑边缘一类的情况,也没有判断矩阵行列是否为0,从左下角开始取值,值得学习,答题是够了。

自己尝试

如果从右上角的话,原理和功能都是一样的,用旋转树的解释就是从根节点了:


class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int i = 0, j = matrix[0].size() - 1;
        while(i < matrix.size() && j >= 0)
        {
            if(matrix[i][j] > target) j--;
            else if(matrix[i][j] < target) i++;
            else return true;
        }
        return false;
    }
};

执行出错信息:

Line 1033: Char 9: runtime error: reference binding to null pointer of type ‘std::vector’ (stl_vector.h)

最后执行的输入:

[] 0

分析原因为如果输入为空矩阵,测试为0的话,预期输出为true,在修改后的代码输出为false,更正后的代码为:

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int i = 0, j = matrix.size() - 1;
        while(i < matrix.size() && j > 0)
        {
            if(matrix[i][j] > target) j--;
            else if(matrix[i][j] < target) i++;
            else return true;
        }
        return false;
    }
};

报错,情况为数组为[[]],测试为0,将while循环里的行判断加上=

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int i = 0, j = matrix.size() - 1;
        while(i <= matrix.size() && j > 0)
        {
            if(matrix[i][j] > target) j--;
            else if(matrix[i][j] < target) i++;
            else return true;
        }
        return false;
    }
};

执行错误输入:

[[-5]] -5

输出:

false

预期:

true

尝试仅仅交换i和j以及对应的增减:


class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        int j = matrix.size() - 1, i = 0;
        while(j >= 0 && i < matrix[0].size())
        {
            if(matrix[i][j] > target) j--;
            else if(matrix[i][j] < target) i++;
            else return true;
        }
        return false;
    }
};

执行出错信息:

AddressSanitizer: heap-buffer-overflow on address 0x603000000358 at pc 0x00000034aead bp 0x7ffcc4aa0610 sp 0x7ffcc4aa0608

最后执行的输入:

[[1,1]] 2,没有办法兼容长方阵,果然还是道行不深,没法操刀,暂时放弃等到之后能力上来了再试图解决。

方法二:


管桦L1

2020-06-11: 一个元素一个元素的找呗,好简单 空间、时间都击败100%用户

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        for(int i = 0 ; i < matrix.length ; i ++){
            for(int j = 0 ; j < matrix[0].length ; j ++){
                if(matrix[i][j] == target){
                    return true;
                }
            }
        }
        return false;
    }
}

方法三:

我要出去乱说L3发布于 2021-02-27437C++

思路:从矩阵右上角开始遍历,若每行末尾的值小于target,则该行全小于target,移动到下一行。直到行末元素大于target,则target必在该行或不存在矩阵中。

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

        int n = matrix.size(), m = matrix[0].size();

        int i = 0, j = m - 1;                           //从右上角开始
        while (i < n && j >= 0)
        {
            if (matrix[i][j] == target) return true;    //每行末尾的值小于target,则该行全小于target
            else if (matrix[i][j] < target) i ++ ;      //该行末尾值大于target,则target只能在该行
            else j -- ;
        }

        return false;
    }
};

判断空矩阵以及是否满足输入要求的部分是值得学习的,如果没有该判断的话,也会卡再前面我尝试过的错误那里。

再改方法一

同样尝试在我前面的代码里也加入这一句:


class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        if (matrix.empty() || matrix[0].empty()) return false;
        int i = 0, j = matrix[0].size() - 1;
        while(i < matrix.size() && j >= 0)
        {
            if(matrix[i][j] > target) j--;
            else if(matrix[i][j] < target) i++;
            else return true;
        }
        return false;
    }
};

哈哈哈,竟然可以了,就是效率有点低:

【剑指Offer】个人学习笔记_ 04_ 二维数组中的查找_第2张图片

那么问题就是出在没有很好的考虑到边缘输入,相信这个功能也可以在while循环条件里实现

教材示例代码

书里的版本先设置了一个bool型参数found,我也参考了这个意见。不过对比发现leetcode上的版本和书里的问题初始设置的代码并不相同。

bool Find(int* matrix, int rows, int columns, int number)
{
    bool found = false;

    if(matrix != nullptr && rows > 0 && columns > 0)
    {
        int row = 0;
        int column = columns - 1;
        while(row < rows && column >=0)
        {
            if(matrix[row * columns + column] == number)
            {
                found = true;
                break;
            }
            else if(matrix[row * columns + column] > number)
                -- column;
            else
                ++ row;
        }
    }

    return found;
}

总结

以上就是本题的内容和学习过程了,万事开头难,加油。

欢迎讨论,共同进步。

你可能感兴趣的:(Coding,c++,leetcode,python,算法)