剑指offer第4题 二维数组中的数字查找

本文记录了一位程序员在LeetCode上刷题的过程,分享了解决二维递增矩阵中查找特定数字的四种方法,包括暴力解法、二分查找和线性搜索。详细阐述了线性搜索的思路,从第一行最右开始,根据元素大小调整搜索方向,直至找到目标或超出边界。代码分别用Python和Go实现。
摘要由CSDN通过智能技术生成

前言

该系列文章为本人刷leetcode的记录,主要旨在分享刷题的思路及算法解析(尽可能的一题多解),另方便自己日后查阅回顾。代码的实现语言是python和go。

想进大厂免不了刷题,一起加油吧,小伙伴们!

(最近实验室的事情实在太多了。只能见缝插针的刷刷题了)

题目

offer 第4题

链接: https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

题目内容

二维数组中的数字查找

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

限制:

0 <= n <= 1000
0 <= m <= 1000

示例 :

现有矩阵 matrix 如下:
[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

解题思路

分析:该题是一个在矩阵中找是否存在指定的元素;考察的重点实际在元素的排序;只不过这里已经将矩阵排成一个从左到右递增,从上到下递增的二维矩阵了;

容易想到的思路:

1.暴力解法;套个双层循环;

2.二分查找法:按行进行二分查找;

3.线性查找:充分利用题目已知条件,从左到右递增,从上到下递增;故可以先直接搜索坐标指向第一行最右元素,如果目标值比其小则搜索坐标向左走一格;如果比其大,则搜索坐标向下走一格;每走完一格后都重复上述比较,直到找到与目标值相等的元素或者是搜索坐标超出界限说明矩阵中没有该元素。

4.巧妙的解法:利用矩阵的特性将其看成二叉搜索树;(该方法一过于有些难想到,不太具有通用性就不展开了)

代码实现

python
class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:

        # #方法1:暴力解法
        if not matrix: return False

        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j]==target:
                    return True
        return False


        #方法2:二分查找;
        #对每一行进行二分查找;

        # if not matrix: return False

        # for row in range(len(matrix)):
        #     left = 0 
        #     right = len(matrix[0])-1 
            
        #     while (left<=right):
        #         mid = int((left+right)/2)

        #         #如果当前中间节点的值比目标值大;说明目标值可能在左边部分;接下来只需要搜索左边空间即可
        #         if matrix[row][mid]>target:right = mid -1 
        #         #如果当前中间节点的值比目标值小;说明目标值可能在右边部分
        #         elif matrix[row][mid]<target : left =mid +1
        #         else: return True
            
        # return False


        #方法3:线性遍历
        # #思路:从第一行最右开始搜索,如果比其小则向左走一格;比起大则向下走一格
        # if not matrix: return False

        # row,col = 0,len(matrix[0])-1

        # while 0<=row<len(matrix) and 0<=col<len(matrix[0]):
        #     if matrix[row][col]>target:col -=1 
        #     elif matrix[row][col]< target: row +=1
        #     else: return True

        # return False



     
go
 func findNumberIn2DArray(matrix [][]int, target int) bool {
    //方法1:暴力解法
    if len(matrix)==0 {return false}
    
    for i:=0; i<len(matrix); i++{
        for j:=0; j<len(matrix[0]); j++{
            if matrix[i][j]==target{return true}
        }
    }

    return false


    //方法2:二分查找
    //稍微优化一下上面的暴力解法
    //按照对每行进行二分查找
    // if len(matrix)==0{return false}

    // row :=0
    // for ;row<len(matrix);row++{
    //     left := 0
    //     right := len(matrix[0])-1

    //     for left<=right{
    //         mid := int((left+right)/2)

    //         //如果中间元素的值比目标值大,说明目标元素可能在左半区间
    //         if matrix[row][mid]>target{right = mid-1
    //         }else if matrix[row][mid]<target {left = mid+1
    //         }else{return true}
    //     }

    // }

    // return false


    //方法3:线性搜索

    // if len(matrix)==0{return false}

    // row := 0 
    // col := len(matrix[0])-1

    // for row>=0 && row<len(matrix) && col>=0 && col<len(matrix[0]){
    //     if matrix[row][col]<target{row++
    //     }else if matrix[row][col]>target{col--
    //     }else{return true}
    // }

    // return false

}

总结

该题主要考察的是排序算法;

注意语法问题,在go中,判断切片是否为空,不能使用nil来判断,需要使用len()==0来判断;以及在go中没有python的便利的数值语法糖:if 0<=row<len(matrix),需要分开写if row>=0 && row<len(matrix)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值