Python算法题集_搜索二维矩阵II

Python算法题集_搜索二维矩阵II

本文为Python算法题集之一的代码示例

题41:搜索二维矩阵II

1. 示例说明

  • 编写一个高效的算法来搜索 *m* x *n* 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

    • 每行的元素从左到右升序排列。
    • 每列的元素从上到下升序排列。

    示例 1:

    复制代码
    输入: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

    示例 2:

    复制代码
    输入: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 = 20
    输出:false

    提示:

    • m == matrix.length
    • n == matrix[i].length
    • 1 <= n, m <= 300
    • -109 <= matrix[i][j] <= 109
    • 每行的所有元素从左到右升序排列
    • 每列的所有元素从上到下升序排列
    • -109 <= target <= 109

2. 题目解析

- 题意分解

  1. 本题为求排序矩阵中是否存在指定的数值
  2. 本题的主要计算有2处,1是元素遍历,2是比较计算
  3. 基本的解法是双层循环,双层遍历,必然能确认是否存在,所以基本的时间算法复杂度为O(n^2)

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 因矩阵行列均已排序,因此可以在每个数组中判断搜索范围

    2. 既可以判断左边界,也可以判断右边界

    3. 对角线的元素有个特点,左上的元素都小于等于它,右下的元素都大于等于它,可以用它控制检索范围


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题很难超时,超时测试用例本地生成,代码详见【4. 最优算法】

3. 代码展开

1) 标准求解【双层循环】

标准双层循环,意外性能还行,看来大家大部分代码都是这么写的,非常简洁

指标优良,超过84%

python 复制代码
import CheckFuncPerf as cfp

def searchMatrix_base(matrix, target) :
 iheight, iwidth = len(matrix), len(matrix[0])
 for iIdx in range(iheight):
     for jIdx in range(iwidth):
         if matrix[iIdx][jIdx] == target:
             return True
 return False

import random,copy
matrix = []
for iIdx in range(1000):
 matrix.append([random.randint(0, 1000000) for x in range(1000)])
for iIdx in range(100):
 matrix[iIdx].sort()
sortedmatrix = [sorted(column) for column in zip(*matrix)]
iTarget = sortedmatrix[888][879]
matrixCopy = copy.deepcopy(sortedmatrix)
result = cfp.getTimeMemoryStr(searchMatrix_base, matrixCopy, iTarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))

# 运行结果
函数 searchMatrix_base 的运行时间为 16.96 ms;内存使用量为 4.00 KB 执行结果 = True

2) 改进版一【行尾检测】

行检测最大值是否过小,有少量优化

指标优异,超越91%

python 复制代码
import CheckFuncPerf as cfp

def searchMatrix_ext1(matrix, target):
 iheight, iwidth = len(matrix), len(matrix[0])
 for iIdx in range(iheight):
     if matrix[iIdx][iwidth-1] >= target:
         for jIdx in range(iwidth):
             if matrix[iIdx][jIdx] == target:
                 return True
 return False

import random,copy
matrix = []
for iIdx in range(1000):
 matrix.append([random.randint(0, 1000000) for x in range(1000)])
for iIdx in range(100):
 matrix[iIdx].sort()
sortedmatrix = [sorted(column) for column in zip(*matrix)]
iTarget = sortedmatrix[888][879]
matrixCopy = copy.deepcopy(sortedmatrix)
result = cfp.getTimeMemoryStr(searchMatrix_ext1, matrixCopy, iTarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))

# 运行结果
函数 searchMatrix_ext1 的运行时间为 16.95 ms;内存使用量为 0.00 KB 执行结果 = True

3) 改进版二【对角线划分】

在对角线判断可能出现区域,计算量最小,但是代码最复杂,调试时间最长,相应维护起来也会更困难;如无绝对必要,不要这么写

表现优异,超过92%

python 复制代码
import CheckFuncPerf as cfp

def searchMatrix_ext2(matrix, target):
 iheight, iwidth = len(matrix), len(matrix[0])
 if matrix[iheight-1][iwidth-1] < target:
     return False
 if matrix[0][0] > target:
     return False
 istart, istop, iminedge = -1, -1, min(iheight, iwidth)
 for iIdx in range(iminedge):
     if matrix[iIdx][iIdx] == target:
         return True
     elif matrix[iIdx][iIdx] < target:
         istart = iIdx
     else:
         istop = iIdx
         break
 if iheight>iwidth:
     for iIdx in range(iwidth, iheight):
         if matrix[iIdx][iwidth-1] >= target:
             for jIdx in range(iwidth):
                 if matrix[iIdx][jIdx] == target:
                     return True
 elif iwidth>iheight:
     for iIdx in range(iheight):
         if matrix[iIdx][iwidth-1] >= target:
             for jIdx in range(iheight, iwidth):
                 if matrix[iIdx][jIdx] == target:
                     return True
 if istop == -1:
     return  False
 for iIdx in range(0, istart+1):
     for jidx in range(istart, iwidth):
         if matrix[iIdx][jidx] == target:
             return True
 for iIdx in range(istart, iheight):
     for jidx in range(0, istop+1):
         if matrix[iIdx][jidx] == target:
             return True
 for iIdx in range(0, iwidth):
     if matrix[istart][iIdx] == target:
         return True
 for iIdx in range(0, iheight):
     if matrix[iIdx][istart] == target:
         return True
 for iIdx in range(0, iwidth):
     if matrix[istop][iIdx] == target:
         return True
 for iIdx in range(0, iheight):
     if matrix[iIdx][istop] == target:
         return True
 return False

import random,copy
matrix = []
for iIdx in range(1000):
 matrix.append([random.randint(0, 1000000) for x in range(1000)])
for iIdx in range(100):
 matrix[iIdx].sort()
sortedmatrix = [sorted(column) for column in zip(*matrix)]
iTarget = sortedmatrix[888][879]
matrixCopy = copy.deepcopy(sortedmatrix)
result = cfp.getTimeMemoryStr(searchMatrix_ext2, matrixCopy, iTarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))

# 运行结果
函数 searchMatrix_ext2 的运行时间为 3.99 ms;内存使用量为 0.00 KB 执行结果 = True

4. 最优算法

根据本地日志分析,最优算法为第3种searchMatrix_ext2

复制代码
import random,copy
matrix = []
for iIdx in range(1000):
    matrix.append([random.randint(0, 1000000) for x in range(1000)])
for iIdx in range(100):
    matrix[iIdx].sort()
sortedmatrix = [sorted(column) for column in zip(*matrix)]
iTarget = sortedmatrix[888][879]
matrixCopy = copy.deepcopy(sortedmatrix)

# 6种算法本地速度实测比较
函数 searchMatrix_base 的运行时间为 16.96 ms;内存使用量为 4.00 KB 执行结果 = True
函数 searchMatrix_ext1 的运行时间为 16.95 ms;内存使用量为 0.00 KB 执行结果 = True
函数 searchMatrix_ext2 的运行时间为 3.99 ms;内存使用量为 0.00 KB 执行结果 = True

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

相关推荐
嘻嘻哈哈樱桃5 分钟前
牛客经典101题解题集--贪心算法+模拟
java·python·算法·贪心算法
AKDreamer_HeXY6 分钟前
QOJ 12255 - 36 Puzzle 题解
数据结构·c++·数学·算法·icpc·qoj
AI科技星15 分钟前
《全域数学》第一部 数术本源 第三卷 代数原本第14篇 附录二 猜想证明【乖乖数学】
人工智能·算法·数学建模·数据挖掘·量子计算
Wect28 分钟前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript
憨波个36 分钟前
【说话人日志】DOVER-Lap:overlap-aware diarization 输出融合算法
人工智能·深度学习·算法·音频·语音识别
叼烟扛炮44 分钟前
C++第四讲:类和对象(下)
c++·算法·类和对象
Rabitebla44 分钟前
vector 的骨架:三根指针、模板陷阱与迭代器失效的第一现场
开发语言·数据结构·c++·算法
BU摆烂会噶1 小时前
【LangGraph】持久化实现的三大能力——人机交互
数据库·人工智能·python·langchain·人机交互
代码不停1 小时前
BFS解决floodfill算法题目练习
算法·宽度优先
.柒宇.1 小时前
AI掘金头条项目部署实践指南
linux·运维·python·fastapi