首页 > 其他分享 >LeetCode刷题之搜索二维矩阵

LeetCode刷题之搜索二维矩阵

时间:2024-07-05 10:59:29浏览次数:20  
标签:int 复杂度 矩阵 查找 搜索 目标值 LeetCode 刷题

2024 7/5 一如既往的晴天,分享几张拍的照片嘿嘿,好几天没做题了,在徘徊、踌躇、踱步。蝉鸣的有些聒噪了,栀子花花苞也都掉落啦,今天给他剪了枝,接回一楼来了。ok,做题啦!
在这里插入图片描述
图1、宿舍阳台摄,每天都是如此美景
在这里插入图片描述
图2、吃饭路上桥上摄
在这里插入图片描述
图3、桥的另一边摄
okok,做题啦!

1、题目描述

在这里插入图片描述

2、算法分析

要求设计一个高效的算法在矩阵中搜索我们想要的元素。我所能想到的就只有暴力解法:

 public boolean searchMatrix(int[][] matrix, int target) {
        for(int[] row : matrix ){
            for(int x : row){
                if(x == target){
                    return true;
                }
            }
        }
        return false;   
    }

暴力解法感觉很爽啊,思路简单。为什么简单的解法往往性能不简单呢?收益高的往往需要更多的付出呢?空间复杂度和时间复杂度往往不能正相关呢?一切似乎都与能量守恒有关。一切似乎都被设定,而我就是一个没有台词的NPC。哈哈,太tm矫情了,矫揉造作,继续想想有没有什么好的方法。
是有的,由于矩阵每一行都是升序排列的,所以我们遍历每一行后,再进行二分查找,看目标值是否在矩阵中。

3、代码

public boolean searchMatrix(int[][] matrix, int target) {
        // 遍历矩阵的每一行  
        for(int[] row : matrix){
            // 对当前行执行二分查找,寻找目标值
            int index = binarySearch(row, target);
            // 如果在当前行找到了目标值(即index >= 0),则返回true
            if(index >= 0){
                return true;
            }
        } 
        // 如果遍历完所有行都没有找到目标值,则返回false
        return false;
    }
    // 定义一个辅助方法,用于对一维数组进行二分查找  
    // 参数:nums是要搜索的一维数组,target是要搜索的目标值  
    // 返回值:如果找到目标值,则返回目标值在数组中的索引;如果没有找到,则返回-1
    public int binarySearch(int[] nums, int target){
        // 初始化查找范围的上下界
        int low = 0, high = nums.length - 1;
        // 当查找范围不为空时,进行查找
        while(low <= high){
            // 计算中间索引,防止溢出 
            int mid = (high - low) / 2 + low;
            // 获取中间元素的值
            int temp = nums[mid];
            // 如果中间元素等于目标值,则返回其索引
            if(temp == target){
                return mid;
            // 如果中间元素大于目标值,则在左半部分继续查找 
            }else if(temp > target){
                high = mid - 1;
            // 如果中间元素小于目标值,则在右半部分继续查找
            }else{
                low = mid + 1;
            } 
        }
        // 如果遍历完整个数组都没有找到目标值,则返回-1
        return -1;
    }

4、复杂度分析

  • 时间复杂度:O(mlogn)。对一行使用二分查找的时间复杂度为 O(logn),最多需要进行 m 次二分查找。
  • 空间复杂度:O(1)

5、Z形查找

okok,还有更妙的一个算法呢,本来打算不写了,发现这个算法妙得很啊,Z字形查找。
Z形查找:

  1. 选择起始搜索点:由于矩阵的每一行和每一列都是有序的,从矩阵的右上角(或左下角,取决于搜索策略)开始搜索是一个很好的选择。这里选择右上角是因为它允许我们同时利用行和列的排序特性。
  2. 比较与移动:在搜索过程中,我们不断地将当前元素与目标值进行比较。如果当前元素等于目标值,则搜索成功,返回true。如果当前元素大于目标值,由于列是升序的,我们可以确定目标值不可能在当前列的更上方(即更靠近矩阵顶部的位置),因此我们将搜索范围缩小到当前列的左方一列。相反,如果当前元素小于目标值,由于行是升序的,我们可以确定目标值不可能在当前行的更左方(即更靠近矩阵左侧的位置),因此我们将搜索范围缩小到当前行的下一行。
  3. 迭代搜索:重复上述比较与移动的过程,直到找到目标值或搜索范围为空(即已经遍历到矩阵的左下角或右上角之外的位置)。
public boolean searchMatrix(int[][] matrix, int target) {
         // 获取矩阵的行数和列数
        int m = matrix.length, n = matrix[0].length;
        // 初始化搜索的起始位置,从矩阵的右上角开始  
        // 选择右上角是因为这样可以同时利用行和列的排序特性来缩小搜索范围
        int x = 0, y = n - 1;
        // 当没有越界时,继续搜索
        while(x < m && y >= 0){
            // 如果当前元素等于目标值,则搜索成功,返回true 
            if(matrix[x][y] == target){
                return true;
            }
            // 如果当前元素大于目标值,由于列是升序的,所以目标值不可能在当前列的更上方  
            // 因此,将搜索范围缩小到当前列的左方一列 
            if(matrix[x][y] > target){
                y--;
            // 如果当前元素小于目标值,由于行是升序的,所以目标值不可能在当前行的更左方  
            // 因此,将搜索范围缩小到当前行的下一行 
            }else{
                x++;
            }
        }
        // 如果遍历完所有可能的搜索范围都没有找到目标值,则返回false 
        return false;
      }

该算法的思想是通过选择合适的起始搜索点,并利用矩阵的行和列都是有序的这一特性,通过不断缩小搜索范围来高效地找到目标值或确定目标值不存在于矩阵中。

复杂度分析——Z查找

  • 时间复杂度:由于每次比较后,搜索范围都会缩小一行或一列,因此该算法的时间复杂度为O(m+n),其中m是矩阵的行数,n是矩阵的列数。这是因为算法最多会遍历矩阵的每一行和每一列各一次。
  • 空间复杂度:该算法的空间复杂度为O(1),因为它只使用了常数个变量来存储搜索过程中的状态(如当前行索引x、当前列索引y以及矩阵的行数m和列数n),而没有使用额外的数据结构来存储搜索过程中的中间结果。

okok,拜拜啦!做完啦

标签:int,复杂度,矩阵,查找,搜索,目标值,LeetCode,刷题
From: https://blog.csdn.net/weixin_48424783/article/details/140200520

相关文章

  • .NET 矩阵6月红队工具和资源集合
    01外网入口打点1.1Sharp4WbemScripting1.2ASP4Eval1.3Sharp4Web.config1.4Sharp4AddScript02安全防御绕过2.1Sharp4DefenderStop03搭建代理隧道3.1Sharp4suo504混淆加密防护4.1Obfuscar混淆器4.2Sharp4BatchGuard05安全技术文档5.1......
  • 玩玩快速冥(LeetCode50题与70题以及联系斐波那契)
    一.算法快速幂今天刷到两个题,比较有意思,还是记录一下.先来讲讲50题.LeetCode50(Pow(x,n))实现pow(x,n),即计算x的整数n次幂函数(即,xn)。这道题一看很平常啊,不就一直乘嘛,循环走一次就够了.但是很抱歉,单纯的想法终究迎来了超时.而且还是个中等的题目,意识到没......
  • Day2 |977.有序数组的平方& 209.长度最小的子数组&59.螺旋矩阵II
    977.有序数组的平方这题太简单了,中间的排序我用的选择排序贴代码了publicint[]sortedSquares(int[]nums){for(inti=0;i<nums.length;i++){nums[i]=nums[i]*nums[i];}for(inti=0;i<nums.length;i++){......
  • 刷题Phuck2--data协议差异
    刷题Phuck2使用arjun扫出hl参数,获取到源码​​源码:<?phpstream_wrapper_unregister('php');if(isset($_GET['hl']))highlight_file(__FILE__);$mkdir=function($dir){system('mkdir--'.escapeshellarg($dir));};......
  • 代码随想录刷题day 2 | 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋矩阵II
    977.有序数组的平方classSolution{publicint[]sortedSquares(int[]nums){int[]ans=newint[nums.length];intleft=0,right=nums.length-1;for(inti=nums.length-1;i>=0;i--){if(nums[right]*nums[righ......
  • oier刷题笔记2024/7/4|康师傅饮用水
    字符串:P4391[BOI2009]RadioTransmission无线传输https://www.luogu.com.cn/problem/P4391kmp的next数组如果next[x]=len(0<len<x),那么就有s[len]=s[x];那么去掉s[x]后得到的[1,x-1]依旧是原串的循环子串,因为x为最短长度,所以可得next[x]一定为0;所以我们可以推论得到n......
  • LeetCode 2528. 最大化城市的最小电量
    2528.最大化城市的最小电量给你一个下标从 0 开始长度为 n 的整数数组 stations ,其中 stations[i] 表示第 i 座城市的供电站数目。每个供电站可以在一定 范围 内给所有城市提供电力。换句话说,如果给定的范围是 r ,在城市 i 处的供电站可以给所有满足 |i-j......
  • LeetCode-刷题记录-滑动窗口合集(本篇blog会持续更新哦~)
    一、滑动窗口概述滑动窗口(SlidingWindow)是一种用于解决数组(或字符串)中子数组(或子串)问题的有效算法。SlidingWindow核心思想:滑动窗口技术的基本思想是维护一个窗口(一般是一个子数组或子串),该窗口在数组上滑动,并在滑动过程中更新窗口的内容。通过滑动窗口,可以在(O(......
  • [Leetcode]Top 150
    链表旋转链表给你一个链表的头节点head,旋转链表,将链表每个节点向右移动k个位置。#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,val=0,next=None):#self.val=val#self.next=nextclassSolution:defro......
  • 如何通俗易懂的理解雅可比矩阵
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、雅可比矩阵是什么?二、更具体的解释:1.多变量函数2.偏导数3.雅可比矩阵为什么雅可比矩阵重要?总结前言雅可比矩阵(Jacobianmatrix)是一个重要的数学概念,尤其在多变量函数微分学中有着广......