【算法】在二维不单调的矩阵上二分查找——力扣1901. 寻找峰值 II

这篇具有很好参考价值的文章主要介绍了【算法】在二维不单调的矩阵上二分查找——力扣1901. 寻找峰值 II。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1901. 寻找峰值 II


【算法】在二维不单调的矩阵上二分查找——力扣1901. 寻找峰值 II

问题描述

给定一个从0开始编号的m x n矩阵mat,其中任意两个相邻格子的值都不相同。峰值是指那些严格大于其相邻格子(上、下、左、右)的元素。需要找出任意一个峰值mat[i][j]并返回其位置[i, j]

示例

示例 1:

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

示例 2:

输入: mat = [[10, 20, 15], [21, 30, 14], [7, 16, 32]]
输出: [1, 1]
解释: 3032 都是峰值,所以[1, 1][2, 2]都是可接受的答案。

解决思路

步骤一:列转行

首先,将矩阵的列转换为行,表示为col[mid]代表原数组第mid列。我们要搜索出col[mid],也就是第mid列的最大值的索引max_idx,以及这一列的最大值max_val

步骤二:回到一维数组上的寻找峰值的思路

现在,只需要确保col[mid][max_idx]大于col[mid - 1][max_idx]col[mid + 1][max_idx]这两个元素。显然,问题的形态与162.寻找峰值非常相似。现在问题转换成了类似在一维数组上的寻找峰值问题的形式。

步骤三:二分搜索

此时,可以使用二分搜索的思路。我们定义le_val = col[mid - 1][max_idx],如果le_val < max_val,说明第mid列有可能包含峰值,也可能是在峰值的列的左侧,此时可以更新left = mid;如果le_val >= max_val,说明mid必定不是峰值,而左边的列有可能是峰值,此时更新right = mid - 1

代码实现

class Solution:
    def findPeakGrid(self, mat: List[List[int]]) -> List[int]:
        m, n = len(mat), len(mat[0])
        cols = list(zip(*mat))

        def get_val(x, y):
            if not (0 <= x < n and 0 <= y < m):
                return -1
            return cols[x][y]

        left, right = 0, n - 1  # n列
        while left < right:
            mid = (left + right + 1) // 2
            max_idx, max_val = max(enumerate(cols[mid]), key=lambda v: v[1])
            le_val = get_val(mid - 1, max_idx)  # 与左边的行作比较
            if le_val < max_val:
                left = mid
            else:
                right = mid - 1

        ans_col = left
        ans_row = max(enumerate(cols[ans_col]), key=lambda v: v[1])[0]
        return [ans_row, ans_col]

二分示意图

二分初始的状态

如图所示,红色的20是mid所指向的列的最大值,获取这个最大值的索引以及值的相关的代码是:

max_idx, max_val = max(enumerate(cols[mid]), key=lambda v: v[1]) 
left mid right
1 2 3 12 13
4 5 6 14 15
7 8 9 16 17
18 19 20 21 22
图1. 二分初始的状态

二分更新说明

因为20比左边的19大,满足le_val < max_val,说明mid所在的这一列或其右侧的列包含峰值,所以,更新left = mid后的情况如下图所示

二分更新后的状态

left mid right
1 2 3 12 13
4 5 6 14 15
7 8 9 16 17
18 19 20 21 22
图2. 二分更新后的状态

性能分析

因为一共有n列,m行,我们是二分查找峰值所在的列,每一次都要遍历一整列上,以找到最大值,一整列上有m个元素,所以,该算法的时间复杂度为O(m log(n)),满足题目要求。文章来源地址https://www.toymoban.com/news/detail-776480.html

到了这里,关于【算法】在二维不单调的矩阵上二分查找——力扣1901. 寻找峰值 II的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Offer必备算法_二分查找_八道力扣OJ题详解(由易到难)

    目录 二分查找算法原理 ①力扣704. 二分查找 解析代码 ②力扣34. 在排序数组中查找元素的第一个和最后一个位置 解析代码 ③力扣69. x 的平方根  解析代码 ④力扣35. 搜索插入位置 解析代码 ⑤力扣852. 山脉数组的峰顶索引 解析代码 ⑥力扣162. 寻找峰值 解析代码 ⑦力扣153. 寻

    2024年02月19日
    浏览(40)
  • 【算法】【Python3、动态规划、贪心、二分查找】力扣1671. 得到山形数组的最少删除次数

    1671. 得到山形数组的最少删除次数 给定一个整数数组 nums ,我们定义该数组为山形数组当且仅当: nums 的长度至少为 3。 存在一个下标 i 满足 0 i len(nums) - 1 且: nums[0] nums[1] ... nums[i - 1] nums[i] nums[i] nums[i + 1] ... nums[len(nums) - 1] 现在,给定整数数组 nums ,我们的目标是将其变为

    2024年01月18日
    浏览(53)
  • 【不单调的代码】还在嫌弃Ubuntu终端?快来试试做些Ubuntu终端的花式玩法。

    🎊专栏【不单调的代码】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Love Story】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 本文是在 Ubuntu环境 下进行编写的,在其他环境下的代码有可能有所不同 目录 注意:   🐂终端中出现会\\\"说话\\\"的牛

    2024年02月08日
    浏览(68)
  • 【算法详解】力扣240.搜索二维矩阵II

    力扣链接:力扣240.搜索二维矩阵II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 题目提到该矩阵是从左到右,从上到下递增的,那么我们就要利用这个性质,从矩阵

    2024年01月21日
    浏览(46)
  • C++二分查找算法:有序矩阵中的第 k 个最小数组和

    二分查找算法合集 C++二分查找算法:查找和最小的 K 对数字 十分接近m恒等于2 给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。 你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。 示例 1: 输入:

    2024年02月05日
    浏览(50)
  • 【题解】二分查找-I、二维数组中的查找

    题目链接:二分查找-I 解题思路:遍历 代码如下: 这种解题思路很明显没有很好的利用题目中强调的数组是升序的,既然是升序,那肯定前半部分偏小,后半部分偏大,如果我们能知道应该去前半部分还是后半部分寻找target,效率相对就提升很多了,于是我们有了下面的分

    2024年02月14日
    浏览(42)
  • 力扣75——二分查找

    总结leetcode75中的 二分查找 算法题解题思路。 上一篇:力扣75——堆/优先队列 题目: 题解: 二分查找。用 left 、 right 分别记录左端点和右端点。然后计算出它们的平均值 mid ,接着用 guess(mid) 判断是大了还是小了。 题目: 题解: 先 快速排序 ,然后用 upper_bound() 找到第一

    2024年02月12日
    浏览(40)
  • Leecode力扣704数组二分查找

    题目链接为:https://leetcode.cn/problems/binary-search/ 最终代码为:   一开始自己写的🐕粑代码为: 问题: C老师的指点和思路: 您的思路是正确的,您正在使用二分搜索法来在有序数组中查找目标值。但是,您的代码有几个问题需要修复: 如果数组中没有找到目标值,while循环

    2024年02月13日
    浏览(43)
  • 【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   mySqrt ( self ,  x :   int )   -   int :       

    2024年02月04日
    浏览(65)
  • 搜索二维矩阵【二分】

    Problem: 74. 搜索二维矩阵 可以二分一次,也可以二分两次。 时间复杂度: 添加时间复杂度, 示例: O ( l o g n + l o g m ) O(logn + logm) O ( l o g n + l o g m ) 空间复杂度: 添加空间复杂度, 示例: O ( 1 ) O(1) O ( 1 )

    2024年02月02日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包