12.19力扣

1901. 寻找峰值 II

题目描述:
  一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子(上、下、左、右)的元素。
  给你一个 从 0 开始编号 的 m x n 矩阵 mat ,其中任意两个相邻格子的值都 不相同 。找出 任意一个 峰值 mat[i][j] 并 返回其位置 [i,j] 。
  你可以假设整个矩阵周边环绕着一圈值为 -1 的格子。
  要求必须写出时间复杂度为 O(m log(n)) 或 O(n log(m)) 的算法。

示例1:(图片源自力扣)
在这里插入图片描述

输入: mat = [[1,4],[3,2]]
输出: [0,1]
解释: 3 和 4 都是峰值,所以[1,0]和[0,1]都是可接受的答案。

示例2:(图片源自力扣)
在这里插入图片描述
输入: mat = [[10,20,15],[21,30,14],[7,16,32]]
输出: [1,1]
解释: 30 和 32 都是峰值,所以[1,1]和[2,2]都是可接受的答案。

解法一:
  这种解法是一种取巧,既然存在峰值,那么我们只要找到最大的那个值,他就一定是峰值。所以我们只需要遍历完找出最大值即可。

class Solution {
public:
    vector<int> findPeakGrid(vector<vector<int>>& mat) {
        int m = mat.size();
        int n = mat[0].size();
        
        int max = 0;
        int max_i = 0, max_j = 0;
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j <= n / 2; j++)
            {
                if(mat[i][j] > max)
                {
                    max_i = i;
                    max_j = j;
                    max = mat[i][j];
                }
                if(mat[i][n - 1 - j] > max)
                {
                    max_i = i;
                    max_j = n - 1 - j;
                    max = mat[i][n - 1 - j];
                }
            }
        }
        return {max_i, max_j};
    }
};

解法二:
  根据峰值出现的位置不同以及矩阵本身的情况,进行一个分类。
  情况一:矩阵只有一个数,那这个数本身就是一个峰值,直接返回。
  情况二:是只有一列或者一行。这种情况下对峰值可能出现的位置进行分类,一个是是出现在头部或者尾部,另一个就是除开头部尾部之外的位置。出现在头部或者尾部就只需要与它相邻的那一个值进行比较久可以判断是否是峰值,另一个情况则是需要与左右的值进行比较,才能判断是否是峰值。
  情况三:是一个正常矩阵,这时把矩阵进行拆分。分为四个角、四条边和中心部分。峰值在四个角时需要在上下、左右的排列组合中进行一个比较来判断是否是峰值。峰值在四条边时,则是与左右的值加上一个值进行比较。峰值在中心部分,则需要与上下左右四个值都进行一次比较才能判断是否是峰值。

class Solution {
public:
    vector<int> findPeakGrid(vector<vector<int>>& mat) {
        int m = mat.size();
        int n = mat[0].size();

        int i = 0, j = 0;
        if(m == 1 && n == 1)
            return {0, 0};

        if(m < 2 || n < 2)
        {
            if(mat[i][j] > mat[i][j + 1])   return {i, j};
            if(mat[i][n - 1] > mat[i][n - 1 - 1]) return {i, n - 1};

            if(mat[i][j] > mat[i + 1][j])   return {i, j};
            if(mat[m - 1][j] > mat[m - 1 - 1][j])   return {m - 1, j};

            for(i = 0; i < m - 2; i++)
            {
                for(j = 0; 0 == i && j < n - 2; j++)
                {
                    if(n < 3)
                    {
                        if(mat[i][j] > mat[i][j + 1])
                            return {i, j};
                        else
                            return {i, j + 1};
                    }
                    if(mat[i][j] < mat[i][j + 1] && mat[i][j + 1] > mat[i][j + 2])
                        return {i, j + 1};
                }
                if(m < 3)
                {
                    if(mat[i][j] > mat[i + 1][j])
                        return {i, j};
                    else
                        return {i + 1, j};
                }
                if(mat[i][j] < mat[i + 1][j] && mat[i + 1][j] > mat[i + 2][j])
                    return {i + 1, j};
            }
        }
        
        // 四个角的数值
        if(mat[i + 1][j] < mat[i][j] && mat[i][j] > mat[i][j +1])   return {i, j};
        j = n - 1;
        if(mat[i][j - 1] < mat[i][j] && mat[i][j] > mat[i + 1][j])   return {i, j};
        i = m - 1;
        if(mat[i - 1][j] < mat[i][j] && mat[i][j] > mat[i][j - 1])   return {i, j};
        j = 0;
        if(mat[i - 1][j] < mat[i][j] && mat[i][j] > mat[i][j + 1])   return {i, j};

        for(i = 0; i < m - 2; i++)
        {
            // 左边
            j = 0;
            if(mat[i][j] < mat[i + 1][j] && mat[i + 1][j] > mat[i + 2][j]
            && mat[i + 1][j] > mat[i + 1][j + 1])
                return {i + 1, j};
            // 右边
            j = n - 1;
            if(mat[i][j] < mat[i + 1][j] && mat[i + 1][j] > mat[i + 2][j]
            && mat[i + 1][j] > mat[i + 1][j - 1])
                return {i + 1, j};
        }
        for(j = 0; j < n - 2; j++)
        {
            // 上边
            i = 0;
            if(mat[i][j] < mat[i][j + 1] && mat[i][j + 1] > mat[i][j + 2]
            && mat[i][j + 1] > mat[i + 1][j + 1])
                return {i, j + 1};
            // 下边
            i = m - 1;
            if(mat[i][j] < mat[i][j + 1] && mat[i][j + 1] > mat[i][j + 2]
            && mat[i][j + 1] > mat[i - 1][j + 1])
                return {i, j + 1};
        }
        
        // 中心
        for(i = 1; i < m - 1; i++)
        {
            for(j = 1; j <= n / 2; j++)
            {
                if(mat[i - 1][j] < mat[i][j] && mat[i][j - 1] < mat[i][j]
                && mat[i + 1][j] < mat[i][j] && mat[i][j + 1] < mat[i][j])
                    return {i, j};
                if(mat[m - i - 1][n - j] < mat[m - i][n - j]
                && mat[m - i][n - j - 1] < mat[m - i][n - j]
                && mat[m - i + 1][n - j] < mat[m - i][n - j]
                && mat[m - i][n - j + 1] < mat[m - i][n - j])
                    return {m - i, n - j};
            }
        }
        return {-1, -1};
    }
};

解法三:
  解法三是力扣官方给的一个解法,说是二分查找,但是我没有看懂,应该用到了某种数学公式。

class Solution {
public:
    vector<int> findPeakGrid(vector<vector<int>>& mat) {
        int m = mat.size();
        int low = 0, high = m - 1;
        while (low <= high) {
            int i = (low + high) / 2;
            int j = max_element(mat[i].begin(), mat[i].end()) - mat[i].begin();
            if (i - 1 >= 0 && mat[i][j] < mat[i - 1][j]) {
                high = i - 1;
                continue;
            }
            if (i + 1 < m && mat[i][j] < mat[i + 1][j]) {
                low = i + 1;
                continue;
            }
            return {i, j};
        }
        return {}; // impossible
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose部署容器可视化管理平台portainer

一、安装docker docker--安装docker-ce-CSDN博客 二、安装docker-compose 安装docker-compose-CSDN博客 三、docker-compose部署portainer yml文件&#xff0c;需要开放9000端口 [rootlgb /]# vi /opt/docker-compose-yml/portainer/docker-compose.yml version: "…

基于JAVA的海南旅游景点推荐系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

jmeter的插件安装以及监控环境使用

1.插件包 下载一个插件管理包jmeter-plugins-manager版本.jar&#xff0c;放到jmeter的lib/ext目录下。 。 重启jmeter&#xff0c;那么就有了插件管理 把JMeterPlugins-Extras.jar和JMeterPlugins-Standard.jar包放进lib/ext目录下 jmeter-plugins-manager-1.4.jar包以及JMe…

2017年第六届数学建模国际赛小美赛C题如何打击人口贩运解题全过程文档及程序

2017年第六届数学建模国际赛小美赛 C题 如何打击人口贩运 原题再现&#xff1a; 7月30日是联合国打击贩卖人口世界日&#xff0c;这一天的重点是结束利用儿童、妇女和男子从事强迫劳动或性工作的犯罪行为。全世界有2700万至4580万人陷于某种形式的现代奴役之中。受害者被迫成…

Unity学习笔记(零基础到就业)|Chapter01:C#入门

Unity学习笔记&#xff08;零基础到就业&#xff09;&#xff5c;Chapter01:C#入门 前言一、控制台输入输出语句二、初识变量1.一些好用的tips2.变量声明的固定写法3.变量类型 三、变量的本质1.变量的存储空间2.变量的本质&#xff1a;2进制 四、变量的命名规范1.必须遵守的规则…

Java 队列(Queue)简介与经典例子

Java 队列&#xff08;Queue&#xff09;简介与经典例子 队列&#xff08;Queue&#xff09;是一种常见的数据结构&#xff0c;它按照先进先出&#xff08;FIFO&#xff09;的原则管理元素。在Java中&#xff0c;队列是一种广泛使用的数据结构&#xff0c;用于处理多种实际问题…

比 style gan 更好的 style gan2

上一篇博客介绍了style gan 原理&#xff0c;但是 style gan 的结果会有水珠伪影&#xff0c;作者实验后发现是 Adain 导致的&#xff0c;AdaIN对每一个feature map的通道进行归一化&#xff0c;这样可能破坏掉feature之间的信息。当然实验证明发现&#xff0c;去除AdaIN的归一…

连接SSH报错 / 连接容器SSH

连接SSH报错 / 连接容器SSH 前言被控端主控端连接失败 前言 本文介绍如何通过SSH方式远程连接Linux被控端&#xff0c;并介绍如何解决连接失败问题。 此方法同样适用于SSH连接Docker容器。 被控端 被控端一般为Linux&#xff0c;默认已安装ssh&#xff0c;但需要手动安装ope…

复杂 SQL 实现分组分情况分页查询

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、根据 camp_status 字段分为 6 种情况 1.1 SQL语句 1.2 SQL解释 二、分页 SQL 实现 2.1 SQL语句 2.2 根据 camp_type 区分返…

[Verilog] Verilog 数据类型

主页&#xff1a; 元存储博客 文章目录 前言1. bit 类型2. reg 类型3 wire类型4 integer类型5 real类型6 parameter类型7 enum类型8 array 类型9 向量类型10 time 类型11 string 类型 前言 在 Verilog 中&#xff0c;有几种不同的数据类型可以用于声明和操作变量。 在 Verilo…

【python】程序运行添加命令行参数argparse模块用法详解

Python标准库之argparse&#xff0c;详解如何创建一个ArgumentParser对象及使用 一. argparse介绍二. 使用步骤及参数介绍三. 具体使用3.1 设置必需参数3.2 传一个参数3.3 传多个参数3.4 位置参数和可选参数3.5 参数设置默认值3.6 其它用法 一. argparse介绍 很多时候&#xff…

遇见小黄鸭——一年开出两千多家门店,疑似员工维权,拖欠薪资?

遇见小黄鸭 遇见小黄鸭&#xff08;重庆&#xff09;食品有限公司成立于2021年10月12日&#xff0c;注册地位于重庆市渝中区 法定代表人为袁林 实际隶属于重庆中润天泽科技&#xff08;集团&#xff09;有限公司 实体业崛起&#xff1f; 经过三年疫情的冲刷&#xff0c;实体…

亚信安慧AntDB:支撑中国广电5G业务的数据库之力

自2019年6月获得5G牌照以来&#xff0c;中国广电积极利用700MHz频谱资源&#xff0c;迅速崛起为第四大运营商&#xff0c;标志着其在数字通信领域取得的巨大成就。通过与中国移动紧密合作&#xff0c;共建共享基站已超过400万座&#xff0c;为实现自主运营和差异化竞争提供了坚…

游戏引擎?

游戏引擎是指一些已编写好的可编辑电脑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具&#xff0c;其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。大部分都支持多种操作平台&#xff0c;如Linux、…

【诊断】linux系统下的内存溢出问题定位

步骤&#xff1a; &#xff08;1&#xff09;编写并运行一个会造成内存溢出的代码&#xff1a; import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger;public class HeapLeakTest {static AtomicInteger i new AtomicInteger(1);public static void …

202. 快乐数(快慢指针)

对于任意n&#xff0c;可能出现以下几种情况&#xff1a; 最终会得到 1。 最终会进入循环。 值会越来越大&#xff0c;最后接近无穷大。 对于第三种情况&#xff0c;我们可以简单的列举一下&#xff1a; 会发现&#xff0c;13位数字的数位平方和最大是1053&#xff0c;1…

LeetCode刷题--- 子集

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题【 http://t.csdnimg.cn/yUl2I 】【C】 【 http://t.csdnimg.cn/6AbpV 】数据结构与算法【 http://t.csdnimg.cn/hKh2l 】 前言&#xff1a;这个专栏主要讲…

多对多关系通用操作组件,省时省力的神器

项目上有很多对多操作的场景&#xff0c;建对象&#xff0c;建mapper接口&#xff0c;设置查询条件&#xff0c;查询多对多数据等都是一项极为耗时耗力的工作。因此&#xff0c;搓了这款集建表-保存-查询-设置条件等操作于一体的组件。原理简单&#xff0c;利用$标签动态作些操…

25.BFD双向转发检查

BFD双向转发检查 链路故障检测工具&#xff0c;结合三层协议使故障检测更加快速 例如两台路由器之间加了一台二层设备 在修改优先级后&#xff0c;默认选择了下面那条优先级高的路由&#xff0c;R1 ping R2的时候是正常能ping通的 但是&#xff0c;当下面的路由出现故障后&a…

基于SpringBoot实现的社区人员管理系统

一、系统架构 前端&#xff1a;html | js | css | layui 后端&#xff1a;springboot | mybaits-plus | shiro 环境&#xff1a;jdk1.8 | mysql8 | maven 二、代码及数据库 三、功能介绍 01. 登录 02. 首页 03. 常规管理-住户模块-住户管理 04. 常规管理-住户模块-高危…
最新文章