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

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

  • 题41:搜索二维矩阵II
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【双层循环】
    • 2) 改进版一【行尾检测】
    • 3) 改进版二【对角线划分】
  • 4. 最优算法

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

题41:搜索二维矩阵II

1. 示例说明

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

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

    示例 1:

    img

    输入: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:

    img

    输入: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%在这里插入图片描述

import CheckFuncPerf as cfpdef 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 Truereturn Falseimport 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%在这里插入图片描述

import CheckFuncPerf as cfpdef 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 Truereturn Falseimport 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%在这里插入图片描述

import CheckFuncPerf as cfpdef searchMatrix_ext2(matrix, target):iheight, iwidth = len(matrix), len(matrix[0])if matrix[iheight-1][iwidth-1] < target:return Falseif matrix[0][0] > target:return Falseistart, istop, iminedge = -1, -1, min(iheight, iwidth)for iIdx in range(iminedge):if matrix[iIdx][iIdx] == target:return Trueelif matrix[iIdx][iIdx] < target:istart = iIdxelse:istop = iIdxbreakif 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 Trueelif 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 Trueif istop == -1:return  Falsefor iIdx in range(0, istart+1):for jidx in range(istart, iwidth):if matrix[iIdx][jidx] == target:return Truefor iIdx in range(istart, iheight):for jidx in range(0, istop+1):if matrix[iIdx][jidx] == target:return Truefor iIdx in range(0, iwidth):if matrix[istart][iIdx] == target:return Truefor iIdx in range(0, iheight):if matrix[iIdx][istart] == target:return Truefor iIdx in range(0, iwidth):if matrix[istop][iIdx] == target:return Truefor iIdx in range(0, iheight):if matrix[iIdx][istop] == target:return Truereturn Falseimport 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 ~

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

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

相关文章

政安晨:政安晨:机器学习快速入门(三){pandas与scikit-learn} {模型验证及欠拟合与过拟合}

这一篇中&#xff0c;咱们使用Pandas与Scikit-liarn工具进行一下模型验证&#xff0c;之后再顺势了解一些过拟合与欠拟合&#xff0c;这是您逐渐深入机器学习的开始&#xff01; 模型验证 评估您的模型性能&#xff0c;以便测试和比较其他选择。 在上一篇中&#xff0c;您已经…

网络请求库axios

一、认识Axios库 为什么选择axios? 功能特点: 在浏览器中发送 XMLHttpRequests 请求在 node.js 中发送 http请求支持 Promise API拦截请求和响应转换请求和响应数据 补充: axios名称的由来? 个人理解没有具体的翻译. axios: ajax i/o system 二、axios发送请求 1.axios请求…

github拉取项目,pycharm配置远程服务器环境

拉取项目 从github上拉取项目到pycharmpycharm右下角选择远程服务器上的环境 2.1. 如图 2.2. 输入远程服务器的host&#xff0c;port&#xff0c;username&#xff0c;password连接 2.3. 选择服务器上的环境 链接第3点 注&#xff1a;如果服务器上环境不存在&#xff0c;先创建…

Qt简易登录界面

代码&#xff1a; #include "mywidget.h" #include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget) {ui->setupUi(this);ui->background->setPixmap(QPixmap(":/qt picture/logo.png"))…

单片机学习笔记---串口向电脑发送数据电脑通过串口控制LED

目录 串口向电脑发送数据 每隔一秒串口就发送一个递增的数给电脑 电脑通过串口控制LED 波特率的具体计算 HEX模式和文本模式 前两节是本节的理论基础&#xff0c;这节开始代码演示&#xff01; 串口向电脑发送数据 接下来先开始演示一下串口单向发送一个数字给电脑&…

【学习笔记】TypeScript编译选项

TS 中的编译选项 我们写了一个TS的文件&#xff0c;我们需要使用如下的命令将我们的TS文件转换为JS文件。 tsc xxx.ts 这样会产生一个对应的js文件 自动编译文件 编译文件时&#xff0c;使用 -W 指令后&#xff0c;TS编译器会自动监视文件的变化&#xff0c;并在文件发生变…

[HTTP协议]应用层的HTTP 协议介绍

目录 1.前言 2.使用fiddler抓包来观察HTTP协议格式 3.HTTP协议的基本格式 2.1请求 2,1.1首行 2.1.2请求头 2.1.3空行 2.2响应 2.2.1首行 2.2.2响应头 键值对 ​编辑2.2.3空行 2.2.4载荷(响应正文) 3.认识URL 3.1关于URL encode 1.前言 我们在前面的博客中,简单的…

windows编程-系统编程入门

1.进程线程概念&#xff08;简略版&#xff09; 1.1 进程 1.1.1 概念 我们编写的代码只是一个存储在硬盘的静态文件&#xff0c;通过编译后就会生成二进制可执行文件&#xff0c;当我们运行这个可执行文件后&#xff0c;它会被装载到内存中&#xff0c;接着 CPU 会执行程序中…

【C++】初识模板:函数模板和类模板

目录 一、模板函数 1、函数模板的概念 2、函数模板的格式 3、函数模板的原理 4、函数模板实例化 5、 模板参数的匹配原则 二、类模板 1 、类模板的定义格式 2 、类模板的实例化 3、模板类示例 一、模板函数 1、函数模板的概念 函数模板代表了一个函数家族&#xff0c…

堆的概念实现

前言 本文将详细讲解堆。堆是一种二叉树&#xff08;一般是完全二叉树&#xff09;使用顺序结构的数组来存储。 tip&#xff1a;这里我们需要注意区分堆在不同地方的含义&#xff0c;这里的堆是一个数据结构&#xff0c;操作系统虚拟进程地址空间的堆是操作系统中管理内存的一块…

备战蓝桥杯---动态规划之背包问题引入

先看一个背包问题的简单版&#xff1a; 如果我们暴力枚举可能会超时。 但我们想一想&#xff0c;我们其实不关心怎么放&#xff0c;我们关心的是放后剩下的体积。 用可行性描述即可。 于是我们令f[i][j]表示前i个物品能否放满体积为j的背包。 f[i][j]f[i-1][j]||f[i-1][j-v…

怎么开启耳穴实操的道路

一.背景 前面的文章耳穴为什么有用&#xff1f;-CSDN博客&#xff0c;我说明了耳穴为什么有用、又是很安全的。 然后又告诉你了颈椎痛的耳穴配方用程序员的思维学习耳穴调理的第一个配方“颈椎病”-CSDN博客。 大胆放手去实操吧&#xff01; 二.工具用什么 1.耳穴贴 由一…