python算法和数据结构刷题[1]:数组、矩阵、字符串

一画图二伪代码三写代码

LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中)-CSDN博客

算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn)

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

【分类整理】面试最常考的 100 道 LeetCode 算法题_算法_负雪明烛-GitCode 开源社区 (csdn.net)

时间复杂度和空间复杂度

时间复杂度

空间复杂度

Day1

数组

遍历、查找、排序、双指针。

53. 最大子数组和 - 力扣(LeetCode)

Kadane算法,动态规划

【数据结构与算法】Kadane‘s算法(动态规划、最大子数组和)_kadane算法-CSDN博客

from typing import Listclass Solution:def maxSubArray(self, nums: List[int]) -> int:if not nums:  # 处理空数组return 0max_sum = current_sum = nums[0]  # 初始化为第一个元素for num in nums[1:]:# 决定是否扩展子数组或重新开始current_sum = max(num, current_sum + num)# 更新全局最大值max_sum = max(max_sum, current_sum)return max_sum
a=Solution()
a. maxSubArray(nums = [-2,1,-3,4,-1,2,1,-5,4])

56. 合并区间 - 力扣(LeetCode)

贪心算法

1.区间排序

2.修改边界值:如果当前区间的左边界大于结果中的最后一个右边界则添加元素到结果中,如果小于等于则更新结果中的右边界。

class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:if len(intervals) == 0: return intervalsintervals.sort(key=lambda x: x[0])result = []for i,num in enumerate(intervals):if len(result)==0 or num[0]>result[-1][1]:result.append(num)else:result[-1][1]=max(result[-1][1],num[1])return result

相似题目:

435. 无重叠区间 - 力扣(LeetCode)

根据区间右边界升序排列;
维护right,代表已留下区间的最大右边界;
遍历排序后的区间:
如果当前区间的左边界 ≥ right,该区间可以留下,更新right
如果当前区间的左边界 < right,该区间去除,更新结果res

class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if not intervals:return 0intervals.sort(key = lambda x : x[1])res = 0right = intervals[0][1]for i in range(1, len(intervals)):if intervals[i][0] < right:res += 1else:right = intervals[i][1]return resa=Solution()
a.  eraseOverlapIntervals(intervals =[[1,2],[2,3],[3,4],[1,3]])

189. 轮转数组 - 力扣(LeetCode)

class Solution:def rotate(self, nums: List[int], k: int) -> None:# 定义反转函数:原地反转 nums[i..j]def reverse(i: int, j: int) -> None:while i < j:nums[i], nums[j] = nums[j], nums[i]  # 交换头尾元素i += 1j -= 1n = len(nums)k %= n  # 处理 k >= n 的情况(如 k=10, n=7 → k=3)reverse(0, n - 1)  # 整体反转reverse(0, k - 1)  # 反转前 k 个元素reverse(k, n - 1)  # 反转剩余元素

切片

class Solution:def rotate(self, nums: List[int], k: int) -> None:k %= len(nums)  nums[:] = nums[-k:] + nums[:-k]

相似题目:

151. 反转字符串中的单词 - 力扣(LeetCode)

class Solution:def reverseWords(self, s: str) -> str:return " ".join(reversed(s.split()))

 238. 除自身以外数组的乘积 - 力扣(LeetCode)

这个属于动态规划中的前后缀分解问题

class Solution:def productExceptSelf(self, nums: List[int]) -> List[int]:n = len(nums)pre = [1] * nfor i in range(1, n):pre[i] = pre[i - 1] * nums[i - 1]suf = [1] * nfor i in range(n - 2, -1, -1):suf[i] = suf[i + 1] * nums[i + 1]return [p * s for p, s in zip(pre, suf)]

​ 

41. 缺失的第一个正数 - 力扣(LeetCode)

哈希表方法:将所有正数存储在哈希表中,从 1 开始递增寻找不在哈希表中的最小正数。

def firstMissingPositive(nums):num_set = set(nums)target = 1while target in num_set:target += 1return target
# 示例调用
print(firstMissingPositive([1, 2, 0]))  # 输出: 3
print(firstMissingPositive([3, 4, -1, 1]))  # 输出: 2
print(firstMissingPositive([7, 8, 9, 11, 12]))  # 输出: 1
  • 时间复杂度:O(N),虽然使用了哈希表,但构建哈希表和查询的总时间仍是线性的。
  • 空间复杂度:O(N),需要额外的空间来存储哈希表。

排序后线性扫描

def firstMissingPositive(nums):nums.sort()target = 1for num in nums:if num == target:target += 1return target
# 示例调用
print(firstMissingPositive([1, 2, 0]))  # 输出: 3
print(firstMissingPositive([3, 4, -1, 1]))  # 输出: 2
print(firstMissingPositive([7, 8, 9, 11, 12]))  # 输出: 1
  • 时间复杂度:O(N log N),主要时间开销来源于排序(排序算法的复杂度为N log N)。
  • 空间复杂度:O(1) 或 O(N),这取决于使用的排序算法。

 利用数组索引作为哈希表

原地哈希技巧用于标记某个数字是否存在于数组中。这种方法的目的是在不使用额外空间的情况下,记录数字的存在情况。

1.将所有非正整数(负数和零)替换为一个不可能出现在结果中的数字(n + 1)

2.遍历数组,将每个数字对应的索引位置的值置为负数,表示该数字存在。

3.遍历数组,找到第一个值为正数的索引位置,该索引加 1 就是缺失的最小正整数。

def firstMissingPositive(nums):n = len(nums)# 将所有的负数和零替换为n+1,n+1是一个不可能出现在合法输出中的数字for i in range(n):if nums[i] <= 0:nums[i] = n + 1# 使用数组索引作为哈希键,通过置负标记存在的数字for i in range(n):num = abs(nums[i])if num <= n:nums[num - 1] = -abs(nums[num - 1])# 寻找第一个大于0的索引位置,即是缺失的最小正数for i in range(n):if nums[i]> 0:return i + 1# 如果数组中包含了1到n的所有数字,则缺失的第一个正数是n+1return n + 1
# 示例调用
print(firstMissingPositive([1, 2, 0]))  # 输出: 3
print(firstMissingPositive([3, 4, -1, 1]))  # 输出: 2
print(firstMissingPositive([7, 8, 9, 11, 12]))  # 输出: 1

矩阵

73. 矩阵置零 - 力扣(LeetCode)

空间复杂度为 O(m+n) 的解法

在这种解法中,我们使用两个集合(或列表)来分别记录需要置零的行和列。

def setZeroes(matrix):if not matrix or not matrix[0]:returnm, n = len(matrix), len(matrix[0])zero_row = set()zero_col = set()# 遍历矩阵,记录需要置零的行和列for i in range(m):for j in range(n):if matrix[i][j] == 0:zero_row.add(i)zero_col.add(j)# 将需要置零的行和列的元素设为0for i in zero_row:for j in range(n):matrix[i][j] = 0for j in zero_col:for i in range(m):matrix[i][j] = 0# 示例
matrix = [[1, 1, 1],[1, 0, 1],[1, 1, 1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1, 0, 1], [0, 0, 0], [1, 0, 1]]

空间复杂度为 O(1) 的解法

算法的空间复杂度是 O(1),因为我们是在原地修改矩阵,没有使用额外的空间

在这种解法中,我们利用矩阵的第一行和第一列来记录其余行和列是否需要置零。但是,我们需要先检查第一行和第一列本身是否包含0。

def setZeroes(matrix):if not matrix or not matrix[0]:returnm, n = len(matrix), len(matrix[0])first_row_zero = any(matrix[0][j] == 0 for j in range(n))first_col_zero = any(matrix[i][0] == 0 for i in range(m))# 使用第一行和第一列作为标记for i in range(1, m):for j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = 0matrix[0][j] = 0# 根据第一行和第一列的标记来置零for i in range(1, m):if matrix[i][0] == 0:for j in range(1, n):matrix[i][j] = 0for j in range(1, n):if matrix[0][j] == 0:for i in range(1, m):matrix[i][j] = 0# 如果第一行原本有0,则将第一行置零if first_row_zero:for j in range(n):matrix[0][j] = 0# 如果第一列原本有0,则将第一列置零if first_col_zero:for i in range(m):matrix[i][0] = 0# 示例
matrix = [[1, 1, 1],[1, 0, 1],[1, 1, 1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1, 0, 1], [0, 0, 0], [1, 0, 1]]

48. 旋转图像 - 力扣(LeetCode)

矩阵顺时针旋转相当于先沿着对角线交换元素,然后反转每一行

class Solution:def rotate(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""n = len(matrix)for i in range(n):# 注意这里j的范围 如果j的范围也是0到n-1那么会出现交换后又交换回来 等于没有交换for j in range(i):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]for line in matrix:line.reverse()

逆时针旋转90度

class Solution:def rotate(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""n = len(matrix)# 既然副对角线为主那么i的范围就是从n-1到0啦 因为python的range是左闭右开所以是n-1和-1for i in range(n-1,-1):# 注意这里j的范围 如果j的范围也是0到n-1那么会出现交换后又交换回来 等于没有交换for j in range(i):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]for line in matrix:line.reverse()

54. 螺旋矩阵 - 力扣(LeetCode)

class Solution(object):def spiralOrder(self, matrix):""":type matrix: List[List[int]]:rtype: List[int]"""result = []while matrix:# 取出矩阵的第一行result += matrix.pop(0)# 旋转矩阵使其再次符合顺时针顺序#zip(*matrix)会将矩阵的行转换为列,
#并返回一个迭代器,而list()将其转换为列表,[::-1]将列表中的元素逆序,从而实现逆时针旋转90度。if matrix:matrix = list(zip(*matrix))[::-1]return result

 240. 搜索二维矩阵 II - 力扣(LeetCode)

二分查找

class Solution:def searchMatrix(self, matrix, target):if not matrix or not matrix[0]:return Falserows, cols = len(matrix), len(matrix[0])x, y = rows - 1, 0  # 从左下角开始while x >= 0 and y < cols:if matrix[x][y] == target:return Trueelif matrix[x][y] < target:y += 1  # 向右移动else:x -= 1  # 向上移动return False# 示例使用
sol = Solution()
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
print(sol.searchMatrix(matrix, target))  # 输出: True

字符串

字符串拼接、切片、查找、替换。

344. 反转字符串 - 力扣(LeetCode)

(版本一) 双指针

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""left, right = 0, len(s) - 1# 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(len(s)//2)更低# 因为while每次循环需要进行条件判断,而range函数不需要,直接生成数字,因此时间复杂度更低。推荐使用rangewhile left < right:s[left], s[right] = s[right], s[left]left += 1right -= 1

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

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

相关文章

【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙

目录 1. 梯度基本计算 2. 控制梯度计算 3. 梯度计算注意 4. 小节 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活…

C++基础day1

前言&#xff1a;谢谢阿秀&#xff0c;指路阿秀的学习笔记 一、基础语法 1.构造和析构: 类的构造函数是一种特殊的函数&#xff0c;在创建一个新的对象时调用。类的析构函数也是一种特殊的函数&#xff0c;在删除所创建的对象时调用。 构造顺序&#xff1a;父类->子类 析…

深入理解linux中的文件(上)

1.前置知识&#xff1a; &#xff08;1&#xff09;文章 内容 属性 &#xff08;2&#xff09;访问文件之前&#xff0c;都必须打开它&#xff08;打开文件&#xff0c;等价于把文件加载到内存中&#xff09; 如果不打开文件&#xff0c;文件就在磁盘中 &#xff08;3&am…

Spring Boot Web项目全解析:从前端请求到后端处理

第一章&#xff1a;对静态资源的整合 ConfigurationProperties(prefix"spring.resources", ignoreUnknownFieldsfalse)public class ResourceProperties implements ResourceLoaderAware {//可以设置和静态资源有关的参数&#xff0c;缓存时间等WebMvcAuotConfigura…

Java创建对象有几种方式?

大家好&#xff0c;我是锋哥。今天分享关于【Java创建对象有几种方式?】面试题。希望对大家有帮助&#xff1b; Java创建对象有几种方式? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Java 中&#xff0c;创建对象有几种常见的方式&#xff0c;具体如下&…

基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…

深入浅出并查集(不相交集合实现思路)

引言 并查集&#xff08;Disjoint Set Union&#xff0c;简称DSU&#xff09;是一种用于处理一些不交集的合并及查询问题。它主要支持两种操作&#xff1a;查找&#xff08;Find&#xff09;和合并&#xff08;Union&#xff09;。 查找&#xff1a;确定某个元素属于哪一个子…

如何运行Composer安装PHP包 安装JWT库

1. 使用Composer Composer是PHP的依赖管理工具&#xff0c;它允许你轻松地安装和管理PHP包。对于JWT&#xff0c;你可以使用firebase/php-jwt这个库&#xff0c;这是由Firebase提供的官方库。 安装Composer&#xff08;如果你还没有安装的话&#xff09;&#xff1a; 访问Co…

享元模式——C++实现

目录 1. 享元模式简介 2. 代码示例 1. 享元模式简介 享元模式是一种结构型模式。 享元模式用于缓存共享对象&#xff0c;降低内存消耗。共享对象相同的部分&#xff0c;避免创建大量相同的对象&#xff0c;减少内存占用。 享元模式需要将对象分成内部状态和外部状态两个部分…

网络原理(4)—— 网络层详解

目录 一. IP协议报头结构 二. 地址管理 2.1 路由器 2.1.1 路由选择 2.1.2 WAN口&#xff08;Wide Area Network&#xff09; 2.1.3 LAN口&#xff08;Local Area Network&#xff09; 2.1.4 WLAN口&#xff08;Wireless Local Area Network&#xff09; 2.2 网段划分…

基于深度学习的输电线路缺陷检测算法研究(论文+源码)

输电线路关键部件的缺陷检测对于电网安全运行至关重要&#xff0c;传统方法存在效率低、准确性不高等问题。本研究探讨了利用深度学习技术进行输电线路关键组件的缺陷检测&#xff0c;目的是提升检测的效率与准确度。选用了YOLOv8模型作为基础&#xff0c;并通过加入CA注意力机…

Android --- handler详解

handler 理解 handler 是一套Android 消息传递机制&#xff0c;主要用于线程间通信。 tips&#xff1a; binder/socket 用于进程间通信。 参考&#xff1a; Android 进程间通信-CSDN博客 handler 就是主线程在起了一个子线程&#xff0c;子线程运行并生成message &#xff0c;l…

vim如何解决‘’文件非法关闭后,遗留交换文件‘’的问题

过程描述&#xff1a; 由于我修改文件时&#xff08;一定得修改了文件&#xff0c;不做任何修改不会产生这个问题&#xff09;的非法关闭&#xff0c;比如直接关闭虚拟机&#xff0c;或者直接断开远程工具的远程连接&#xff0c;产生了以下遗留交换文件的问题&#xff1a; 点击…

六十分之三十七——一转眼、时光飞逝

一、目标 明确可落地&#xff0c;对于自身执行完成需要一定的努力才可以完成的 1.第三版分组、激励、立体化权限、智能设备、AIPPT做课 2.8本书 3.得到&#xff1a;头条、吴军来信2、卓克科技参考3 4.总结思考 二、计划 科学规律的&#xff0c;要结合番茄工作法、快速阅读、…

Linux环境下的Java项目部署技巧:安装 Mysql

查看 myslq 是否安装&#xff1a; rpm -qa|grep mysql 如果已经安装&#xff0c;可执行命令来删除软件包&#xff1a; rpm -e --nodeps 包名 下载 repo 源&#xff1a; http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm 执行命令安装 rpm 源(根据下载的…

css三角图标

案例三角&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

Shadow DOM举例

这东西具有隔离效果&#xff0c;对于一些插件需要append一些div倒是不错的选择 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"utf-8"> <title>演示例子</title> </head> <body> <style&g…

万字长文深入浅出负载均衡器

前言 本篇博客主要分享Load Balancing&#xff08;负载均衡&#xff09;&#xff0c;将从以下方面循序渐进地全面展开阐述&#xff1a; 介绍什么是负载均衡介绍常见的负载均衡算法 负载均衡简介 初识负载均衡 负载均衡是系统设计中的一个关键组成部分&#xff0c;它有助于…

ChatGPT-4o和ChatGPT-4o mini的差异点

在人工智能领域&#xff0c;OpenAI再次引领创新潮流&#xff0c;近日正式发布了其最新模型——ChatGPT-4o及其经济实惠的小型版本ChatGPT-4o Mini。这两款模型虽同属于ChatGPT系列&#xff0c;但在性能、应用场景及成本上展现出显著的差异。本文将通过图文并茂的方式&#xff0…

双指针算法思想——OJ例题扩展算法解析思路

大家好&#xff01;上一期我发布了关于双指针的OJ平台上的典型例题思路解析&#xff0c;基于上一期的内容&#xff0c;我们这一期从其中内容扩展出来相似例题进行剖析和运用&#xff0c;一起来试一下吧&#xff01; 目录 一、 基于移动零的举一反三 题一&#xff1a;27. 移除…