【PythonCode】力扣Leetcode11~15题Python版

2024-04-13 08:52

本文主要是介绍【PythonCode】力扣Leetcode11~15题Python版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【PythonCode】力扣Leetcode11~15题Python版

前言

力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台,很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。
在Leetcode上刷题,可以选择各种主流的编程语言,如C++、JAVA、Python、Go等。还可以在线编程,实时执行代码,如果代码通过了平台准备的测试用例,就可以通过题目。
本系列中的文章从Leetcode的第1题开始,记录我用Python语言提交的代码和思路,供Python学习参考。

11. 盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

在这里插入图片描述

示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1]
输出:1
提示:
n == height.length
2 <= n <= 105
0 <= height[i] <= 104

代码实现:

class Solution:def maxArea(self, height: List[int]) -> int:i, j = 0, len(height) - 1max_area = 0while i < j:max_area = max(max_area, (j-i) * min(height[i], height[j]))if height[i] < height[j]:i += 1else:j -= 1return max_area

解题思路:根据题意,本题求的结果是一个长方形的面积,目的是在数组中找到两个数,使它们围成的长方形面积最大。如果这两个数在数组中的索引分别为i和j,那长方形的宽就是 j-i ,长方形的高就是 height[i]和height[j] 中较小的一个。分析到这里,原理基本就清楚了,最粗暴的方式就是遍历数组中所有 i和j 的组合,以找到最大面积,但是这种方式的时间复杂度为 O(N^2),不能通过测试,所以要进行优化。

解题时,可以使用双指针方式,i 初始指向数组的第一个元素,j 初始指向数组的最后一个元素,在初始状态下,长方形的宽度 j-i 是最大的,当指针移动时,宽度不断变小。在宽度不断变小的情况下,如果想得到更大的面积,肯定要找到更高的值,才有可能,所以,每次都保留值更大的指针,移动值更小的指针,看能否找到更大的数,直到指针相遇。指针移动的过程中不断更新最大面积,最后将值返回。这样时间复杂度为 O(N),满足题目要求。

12. 整数转罗马数字

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

例如, 罗马数字 2 写做 II ,即为两个并列的 I。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给你一个整数,将其转为罗马数字。

示例 1:
输入: num = 3
输出: “III”
示例 2:
输入: num = 4
输出: “IV”
示例 3:
输入: num = 9
输出: “IX”
示例 4:
输入: num = 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999

代码实现:

class Solution:def intToRoman(self, num: int) -> str:ones = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]tens = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]hundreds = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]thousands = ["", "M", "MM", "MMM"]return thousands[num//1000] + hundreds[num%1000//100] + tens[num%100//10] + ones[num%10]

解题思路:根据罗马数字的规则,个、十、百、千的表示字母各不相同。所以,要将一个整数转换成罗马数字,可以先分解一下,分别将数字的个位数、十位数、百位数、千位数依次转换成罗马数字,再拼接在一起就可以了。

题目规定的数字在1-3999之间,所以在代码中,可以先初始化几个数组,分别表示1-9, 10-90, 100-900, 1000-3000的罗马数字,并且每个数组都要加上0(空字符)。计算数字的千位、百位、十位、个位,并从数组中取出对应的值拼接即可完成转换。

13. 罗马数字转整数

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。

示例 1:
输入: s = “III”
输出: 3
示例 2:
输入: s = “IV”
输出: 4
示例 3:
输入: s = “IX”
输出: 9
示例 4:
输入: s = “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: s = “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= s.length <= 15
s 仅含字符 (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’)
题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。

代码实现:

class Solution:def romanToInt(self, s: str) -> int:roman = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}sum = 0for i in range(len(s) - 1):if roman[s[i]] >= roman[s[i+1]]:sum += roman[s[i]]else:sum -= roman[s[i]]return sum + roman[s[-1]]

解题思路:本题是上一题的逆转换,但是代码并不是完全一样的思路。根据罗马数字的规则,通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。也就是说,如果罗马数字中小的数字在大的数字的右边,那么是加的关系,如果罗马数字中小的数字在大的数字的左边,那么是减的关系。

所以要完成罗马数字转整数,只需要遍历罗马数字中的每个符号,如果符号比它的后一个符号大,则加上该符号表示的数值,如果符号比它的后一个符号小,则减掉符号的值。

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
示例 2:
输入:strs = [“dog”,“racecar”,“car”]
输出:“”
解释:输入不存在公共前缀。
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成

代码实现:

class Solution:def longestCommonPrefix(self, strs: List[str]) -> str:for i in range(len(strs[0])):for s in strs[1:]:if len(s) == i or s[i] != strs[0][i]:return strs[0][0: i]return strs[0]

解题思路:本地要返回的是多个字符串的公共前缀,最后的返回结果也是一个字符串,如果没有公共前缀则返回空字符串。公共前缀是每一个字符串中都有的字符,并且都在字符串的开头,位置和顺序也一样。所以可以先从第一个字符串 strs[0] 中的第一个字符开始寻找,依次取出第一个字符串中的每个字符,遍历其他字符串,对比相同索引位的字符是否相等,如果遇到字符不相等则停止遍历,返回第一个字符串中前面的字符,就得到公共前缀。

同时,每个字符串的长度不一定相同,其他字符串的长度可能比第一个字符串更短,所以如果对比到了第 i 个字符,遇到一个字符串的长度只有 i-1,则停止遍历。

上面的代码中,先计算第一个字符串的长度,用索引从第一个字符串的第一个字符开始遍历,然后遍历剩余字符串,并进行条件判断,遇到不匹配时,返回结果。Python比较巧妙的一点是可以使用切片语法,让代码更简洁。此外,假如 strs 中只有一个字符串,遍历的代码跑不进去,这种情况应直接返回 strs[0] 。

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

代码实现:

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums.sort()result = []for i in range(len(nums) - 2):if i > 0 and nums[i] == nums[i - 1]:continueif nums[i] > 0:breakk = len(nums) - 1for j in range(i + 1, len(nums) - 1):if j > i + 1 and nums[j] == nums[j - 1]:continuewhile j < k and nums[i] + nums[j] + nums[k] > 0:k -= 1if j == k:breakif nums[i] + nums[j] + nums[k] == 0:result.append([nums[i], nums[j], nums[k]])return result

解题思路:根据题意,要在数组中找到三个数,使三个数之和为0,并且每个组合中不能重复利用同一个数字,最终要返回所有可能的不重复组合。因为结果是不重复的组合,并且题目也不要求数字组合的顺序与原数组一样,为了方便解题,可以先对数组进行排序。

排序后先取第一个数,就是遍历数组中的第一个到倒数第三个数字,如果遇到相等的数字就跳过,因为这种情况得到的组合是重复的。如果遇到大于0的数字就退出循环,因为已经将数组排序了,如果第一个数字大于0,后面的数字都大于或等于第一个数字,三个数的和不可能等于0。

取了第一个数,继续嵌套遍历取第二个数,即从第一个数字的后一个数字遍历到数组的倒数第二个数字,同理如果遇到相等的数字就跳过。

在遍历第二个数字的同时,可以用指针从数组的最后一个数字开始获取第三个数字,并在遍历的过程中计算三个数字的和。如果三个数的和等于0,说明找到了一种组合,将这种组合保存下来。如果三个数的和小于0,则说明当前找不到第三个数来与前两个数组合,不需要做处理,继续遍历改变前两个数。如果三个数的和大于0,则向左移动指针,使第三个数变小,直到找到满足和为0的组合或指针与第二个数的索引相遇。用指针的方式获取第三个数字,可以降低整体的时间复杂度。


相关阅读

PythonCode】力扣Leetcode6~10题Python版

📢欢迎 点赞👍 收藏⭐ 评论📝 关注 如有错误敬请指正!

☟ 学Python,点击下方名片关注我。☟

这篇关于【PythonCode】力扣Leetcode11~15题Python版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/899690

相关文章

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

使用Python开发Markdown兼容公式格式转换工具

《使用Python开发Markdown兼容公式格式转换工具》在技术写作中我们经常遇到公式格式问题,例如MathML无法显示,LaTeX格式错乱等,所以本文我们将使用Python开发Markdown兼容... 目录一、工具背景二、环境配置(Windows 10/11)1. 创建conda环境2. 获取XSLT

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

PyQt5+Python-docx实现一键生成测试报告

《PyQt5+Python-docx实现一键生成测试报告》作为一名测试工程师,你是否经历过手动填写测试报告的痛苦,本文将用Python的PyQt5和python-docx库,打造一款测试报告一键生成工... 目录引言工具功能亮点工具设计思路1. 界面设计:PyQt5实现数据输入2. 文档生成:python-

Python中Flask模板的使用与高级技巧详解

《Python中Flask模板的使用与高级技巧详解》在Web开发中,直接将HTML代码写在Python文件中会导致诸多问题,Flask内置了Jinja2模板引擎,完美解决了这些问题,下面我们就来看看F... 目录一、模板渲染基础1.1 为什么需要模板引擎1.2 第一个模板渲染示例1.3 模板渲染原理二、模板

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例