【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

相关文章

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

Python 字符串占位

在Python中,可以使用字符串的格式化方法来实现字符串的占位。常见的方法有百分号操作符 % 以及 str.format() 方法 百分号操作符 % name = "张三"age = 20message = "我叫%s,今年%d岁。" % (name, age)print(message) # 我叫张三,今年20岁。 str.format() 方法 name = "张三"age

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

python 喷泉码

因为要完成毕业设计,毕业设计做的是数据分发与传输的东西。在网络中数据容易丢失,所以我用fountain code做所发送数据包的数据恢复。fountain code属于有限域编码的一部分,有很广泛的应用。 我们日常生活中使用的二维码,就用到foutain code做数据恢复。你遮住二维码的四分之一,用手机的相机也照样能识别。你遮住的四分之一就相当于丢失的数据包。 为了实现并理解foutain

python 点滴学

1 python 里面tuple是无法改变的 tuple = (1,),计算tuple里面只有一个元素,也要加上逗号 2  1 毕业论文改 2 leetcode第一题做出来

力扣SQL50 每位经理的下属员工数量 join

Problem: 1731. 每位经理的下属员工数量 👨‍🏫 参考题解 Code select m.Employee_id, m.name,count(*) reports_count,round(avg(e.age),0) average_agefrom Employees ejoin Employees mon e.reports_to = m.Employee_id

Python爬虫-贝壳新房

前言 本文是该专栏的第32篇,后面会持续分享python爬虫干货知识,记得关注。 本文以某房网为例,如下图所示,采集对应城市的新房房源数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93aC5mYW5nLmtlLmNvbS9sb3VwYW4v 目标:采集对应城市的

python 在pycharm下能导入外面的模块,到terminal下就不能导入

项目结构如下,在ic2ctw.py 中导入util,在pycharm下不报错,但是到terminal下运行报错  File "deal_data/ic2ctw.py", line 3, in <module>     import util 解决方案: 暂时方案:在终端下:export PYTHONPATH=/Users/fujingling/PycharmProjects/PSENe