leetcode之hot100---240搜索二维矩阵II(C++)

思路一:通过遍历主对角线上元素判断查找方向

  • 主对角线遍历

    • 遍历主对角线上的每个元素(matrix[i][i]),其中 i 的范围是 [0, min(m, n) - 1]
    • 如果目标值小于当前主对角线元素,说明目标值可能在当前元素的左上区域(即当前行的左侧或当前列的上方)。
    • 如果目标值大于主对角线上的所有元素,则需要在剩余的行和列中继续查找。
  • 二分查找辅助函数

    • binarySearchRow:在给定的行范围 [0, colLimit-1] 上进行二分查找。
    • binarySearchCol:在给定的列范围 [0, rowLimit-1] 上进行二分查找。
  • 查找策略

    • 每次遍历主对角线元素时,通过二分查找缩小范围,分别查找目标值是否在当前行或当前列中。
#include <vector>
#include <algorithm> // for std::lower_bound
using namespace std;class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size();int n = matrix[0].size();int len = min(m, n); // 主对角线的长度for (int i = 0; i < len; ++i) {// 如果主对角线上的元素等于目标值,直接返回 trueif (matrix[i][i] == target) {return true;}// 如果目标值小于主对角线上的元素,目标可能在当前行的左侧或当前列的上方if (matrix[i][i] > target) {// 在第 i 行的左侧 [0, i-1] 范围内查找if (binarySearchRow(matrix, target, i)) {return true;}// 在第 i 列的上方 [0, i-1] 范围内查找if (binarySearchCol(matrix, target, i)) {return true;}// 如果在当前行和列都没有找到,直接返回 falsereturn false;}}// 如果目标值大于主对角线上的所有元素,则在剩余行和列中查找return false;}private:// 在第 rowIndex 行的 [0, colLimit-1] 范围内进行查找bool binarySearchRow(const vector<vector<int>>& matrix, int target, int rowLimit) {auto it = lower_bound(matrix[rowLimit].begin(), matrix[rowLimit].begin() + rowLimit, target);return it != matrix[rowLimit].begin() + rowLimit && *it == target;}// 在第 colIndex 列的 [0, rowLimit-1] 范围内进行查找bool binarySearchCol(const vector<vector<int>>& matrix, int target, int colLimit) {vector<int> column;for (int i = 0; i < colLimit; ++i) {column.push_back(matrix[i][colLimit]);}auto it = lower_bound(column.begin(), column.end(), target);return it != column.end() && *it == target;}
};
  • 时间复杂度O((min(m, n))²)
  • 空间复杂度O(min(m, n))

思路二:暴力解法

遍历矩阵,查找成功返回true,否则返回false

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size();int n = matrix[0].size();//矩阵为空查找失败if(n == 0){return false;}//目标越界查找失败if(target < matrix[0][0] || target > matrix[m - 1][n - 1]){return false;}for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(matrix[i][j] == target){return true;}}}//遍历整个矩阵没找到目标值,查找失败return false;}
};
  • 时间复杂度:O(m * n)
  • 空间复杂度:O(1)

思路三:二分查找

由于矩阵内部数字是升序的,在每一行中进行二分查找,查找成功返回true,否则返回false

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {//遍历矩阵中第一列的所有元素for(auto &row: matrix){//在每一行中进行二分查找auto it = lower_bound(row.begin(), row.end(), target);//查找成功返回trueif(it != row.end() && *it == target){return true;}}//查找不成功返回falsereturn false;}
};
  • 时间复杂度:O(nlogn),注:二分查找算法的时间复杂度为O(logn)
  • 空间复杂度:O(1)

获取迭代器值的四种方法: 

  1. 使用解引用运算符 *
    vector<int> vec = {1, 3, 5, 7, 9};
    auto it = lower_bound(vec.begin(), vec.end(), 3);
    int value = *it;  // 直接获取值
  2. 获取下标位置(仅适用于连续容器如vector)
    vector<int> vec = {1, 3, 5, 7, 9};
    auto it = lower_bound(vec.begin(), vec.end(), 3);
    int index = it - vec.begin();  // 获取下标位置
    int value = vec[index];        // 通过下标获取值
  3. 对于pair或结构体类型,使用箭头运算符 ->
    vector<pair<int, string>> vec = {{1,"a"}, {3,"b"}, {5,"c"}};
    auto it = lower_bound(vec.begin(), vec.end(), make_pair(3, ""));
    int first = it->first;      // 获取pair的first
    string second = it->second; // 获取pair的second
  4. 使用迭代器的distance函数获取位置
    vector<int> vec = {1, 3, 5, 7, 9};
    auto it = lower_bound(vec.begin(), vec.end(), 3);
    int index = distance(vec.begin(), it);
    

 注意:在使用迭代器之前,应该先检查迭代器是否有效,避免解引用end()迭代器。

思路四:Z字形查找 

从右上角向左下角,如果当前遍历到的数字大于目标值,就向左移动,如果当前遍历到的数字小于目标值,就向下移动,遍历到目标值返回true,否则返回false

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size();int n = matrix[0].size();//(x,y)为矩阵右上角数字的坐标int x = 0, y = n - 1;//从右上角开始向左下角遍历while(x < m && y >= 0){//查找成功返回trueif(matrix[x][y] == target){return true;}// 如果当前值大于目标值,则向左移动一列// (因为矩阵的每一行从左到右递增)else if(matrix[x][y] > target){--y;}// 如果当前值小于目标值,则向下移动一行// (因为矩阵的每一列从上到下递增)else{++x;}}// 如果遍历结束仍未找到目标值,返回 falsereturn false;}
};
  • 时间复杂度:O(m+n)
  • 空间复杂度:O(1)

 同时也可以从左下角向右上角进行查找,只需要基于上述代码进行少量修改:

int x = m - 1, y = 0;
//从左下角开始向右上角遍历
while(x >= 0 && y < n){//查找成功返回trueif(matrix[x][y] == target){return true;}// 如果当前值大于目标值,则向上移动一列// (因为矩阵的每一行从上到下递增)else if(matrix[x][y] > target){--x;}// 如果当前值小于目标值,则向右移动一行// (因为矩阵的每一列左到右递增)else{++y;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494096.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习记录】浏览器指纹相关学习记录(指纹介绍、获取指纹、修改指纹、随机指纹保护隐私等)

用途 不需要用户登录&#xff0c;可以识别是同一个用户&#xff0c;用于反爬虫广告推送等一类的场景 指纹在线查询地址 http://www.fingerprintbrowser.com/ CreepJS 浏览器指纹在线检测网站:代理IP防关联伪装度查询工具 IP检测大师 【自动化】Python SeleniumUtil 工具 开…

redis数据转移

可能有时候因为硬件的原因我们我们需要更换服务器&#xff0c;如果更换服务器的话&#xff0c;那我们redis的数据该怎样转移呢&#xff0c;按照一下步骤即可完成redis数据的转移 1.进入redis客户端 2.使用 bgsave命令进行数据的备份&#xff0c;此命令完成后会在你的redis安装目…

【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

腾讯云智能结构化OCR:以多模态大模型技术为核心,推动跨行业高效精准的文档处理与数据提取新时代

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大三学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

登山第十六梯:深度恢复——解决机器人近视问题

文章目录 一 摘要 二 资源 三 内容 一 摘要 深度感知是基于 3D 视觉的机器人技术的一个重要问题。然而&#xff0c;现实世界的主动立体或 ToF 深度相机经常会产生嘈杂且深度不完整&#xff0c;从而成为机器人性能的瓶颈。在这项工作中&#xff0c;提出了 一个基于学习的立体…

Leetcode中最常用的Java API——util包

前言&#xff1a;在刷力扣的时候是核心代码模式&#xff0c;笔试的时候很可能是ACM模式&#xff0c;需要自己完成导包、定义和自行设计输出&#xff0c;所以一些常用的类和方法需要先导入相应的API包&#xff0c;java.util就是最常用到的包&#xff0c;因为它包含集合这个大框架…

JVM对象分配内存如何保证线程安全?

大家好&#xff0c;我是锋哥。今天分享关于【JVM对象分配内存如何保证线程安全&#xff1f;】面试题。希望对大家有帮助&#xff1b; JVM对象分配内存如何保证线程安全&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中&#xff0c;对象的内存分配…

前端使用 Konva 实现可视化设计器(20)- 性能优化、UI 美化

这一章主要分享一下使用 Konva 遇到的性能优化问题&#xff0c;并且介绍一下 UI 美化的思路。 至少有 2 位小伙伴积极反馈&#xff0c;发现本示例有明显的性能问题&#xff0c;一是内存溢出问题&#xff0c;二是卡顿的问题&#xff0c;在这里感谢大家的提醒。 请大家动动小手&a…

AIGC-------AI生成内容如何赋能AR和VR体验?

AI生成内容如何赋能AR和VR体验 引言 增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08;VR&#xff09;技术近年来蓬勃发展&#xff0c;为用户提供了沉浸式的体验。这些技术已经广泛应用于游戏、教育、医疗、建筑等领域。然而&#xff0c;AR和VR体验的质量与内容的丰富…

VLM--CLIP作分类任务的损失函数

info_nce_loss 这个是clip作对比学习的损失函数 各个博客上都有详细介绍了&#xff0c;我这里就不赘述 def info_nce_loss(image_features, text_features,logit_scale,labels, temperature0.07):batch_size image_features.shape[0]image_features image_features / image…

【模型压缩】原理及实例

在移动智能终端品类越发多样的时代&#xff0c;为了让模型可以顺利部署在算力和存储空间都受限的移动终端&#xff0c;对模型进行压缩尤为重要。模型压缩&#xff08;model compression&#xff09;可以降低神经网络参数量&#xff0c;减少延迟时间&#xff0c;从而实现提高神经…

leetcode-128.最长连续序列-day14

为什么我感觉上述代码时间复杂度接近O(2n), 虽然有while循环&#xff0c;但是前面有个if判断&#xff0c;能进入while循环的也不多&#xff0c;while循环就相当于两个for循环&#xff0c;但不是嵌套类型的&#xff1a; 变量作用域问题&#xff1a;

Burp与其他安全工具联动及代理设置教程

Burp Suite 是一款功能强大的 Web 安全测试工具&#xff0c;其流量拦截和调试功能可以与其他安全工具&#xff08;如 Xray、Yakit、Goby 等&#xff09;实现联动&#xff0c;从而提升渗透测试的效率。本文将详细讲解 Burp 与其他工具联动的原理以及代理设置的操作方法&#xff…

文件操作(File类)

目录 一、初识文件 二、File类 常用方法 一、初识文件 我们目前是如何存储数据的?弊端是什么? int a 1; int[] arr new int[5];我们这些数据是在内存中存储的&#xff0c;是不能够长久保存的。 那么&#xff0c;我们的计算机当中有没有一块硬件可以长久存储数据的? 磁…

Ubuntu硬盘分区及挂载(命令行)

文章目录 一、简介二、硬盘分区三、格式化分区四、自动挂载分区五、调整分区大小小结 一、简介 创建磁盘分区首先需要找出Linux系统中的物理磁盘&#xff0c;在Linux中采用了一种标准格式来为硬盘分配设备名称。 SATA驱动器和SCSI驱动器&#xff1a;设备命名格式为/dev/sdx&a…

用java造1万条数据

上个月项目有造数需求记录一下。 package com.company;public class CreateSqlZhou {public static void main(String[] args) {//insert into Student (id,name,sex,age,adress) values(68881624120312320,zhangsan,男,18,北京);String startSql "insert into Student…

vue iframe进行父子页面通信并切换URL

需求是2个项目需要使用同一个面包屑进行跳转&#xff0c;其中一个是iframe所在的项目&#xff0c;另一个需要通过地址访问。通过 window.parent.postMessage &#xff0c;帮助 <iframe> 内嵌入的子页面和其父页面之间进行跨域通信。 使用通义千问提问后得到一个很好的示…

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

UVM 验证方法学之interface学习系列文章(十二)virtual interface 终结篇

一 双向和三态问题 任何具有多个驱动器的信号,都需要使用网(net)来建模。网是唯一能够同时解决不同状态和强度驱动同一信号效果的构造。net的行为由内置解析函数定义,该函数使用net上所有驱动器的值和强度。每当其中一个驱动器发生变化时,就会调用该函数来生成解析值。该…

【游戏设计原理】22 - 石头剪刀布

一、游戏基础&#xff1a;拳头、掌心、分指 首先&#xff0c;石头剪刀布&#xff08;又名“Roshambo”&#xff09;看似简单&#xff0c;实际上可是个“深藏玄机”的零和博弈&#xff08;听起来很高深&#xff0c;其实就是输赢相抵消的意思&#xff09;。游戏中有三种手势&…