【PythonCode】力扣Leetcode11~15题Python版

news2024/11/27 9:36:19

【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) - 1
        max_area = 0
        while i < j:
            max_area = max(max_area, (j-i) * min(height[i], height[j]))
            if height[i] < height[j]:
                i += 1
            else:
                j -= 1
        return 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 = 0
        for 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]:
                continue
            if nums[i] > 0:
                break
            k = len(nums) - 1
            for j in range(i + 1, len(nums) - 1):
                if j > i + 1 and nums[j] == nums[j - 1]:
                    continue
                while j < k and nums[i] + nums[j] + nums[k] > 0:
                    k -= 1
                if j == k:
                    break
                if 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,点击下方名片关注我。☟

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

316_C++_xml文件解析成map,可以放到表格上 + xml、xlsx文件互相解析

xml文件例如&#xff1a; <?xml version"1.0" encoding"UTF-8" standalone"yes"?> <TrTable> <tr id"0" label"TR_PB_CH" text"CH%2"/> <tr id"4" label"TR_PB_CHN"…

[BT]BUUCTF刷题第16天(4.12)

第16天 Web [MRCTF2020]Ezpop 打开网站就是一段泄露的源代码&#xff1a; <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack…

Ollama、FastGPT大模型RAG结合使用案例

参考: https://ollama.com/download/linux https://doc.fastai.site/docs/intro/ https://blog.csdn.net/m0_71142057/article/details/136738997 https://doc.fastgpt.run/docs/development/custom-models/m3e/ Ollama作为后端大模型加载运行 FastGPT作为前端页面聊天集成RA…

Linux函数学习 select

1、Linux select 函数 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); nfds 最大文件fd 1 readfds 监听可读文件集合fd writefds 监听可写文件集合fd exceptfd 监听异常文件集…

[蓝桥杯] 岛屿个数(C语言)

提示&#xff1a; 橙色字体为需要注意部分&#xff0c;红色字体为难点部分&#xff0c;会在文章“重难点解答”部分精讲。 题目链接 蓝桥杯2023年第十四届省赛真题-岛屿个数 - C语言网 题目理解 这道题让我们求岛屿个数&#xff0c;那么我们就应该先弄懂&#xff0c;对于一…

R: 支持向量机(Support Vector Machine,简称SVM)

在数据科学和机器学习领域中&#xff0c;支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是一种强大的监督学习算法&#xff0c;常用于分类和回归分析。它的优点之一是可以适用于复杂的数据集&#xff0c;并且在高维空间中表现良好。在本文中&am…

SpringBoot3 + Vue3 + Uniapp + uView + Elenment 实现动态二级分类以及二级分类的管理

SpringBoot3 Vue3 Uniapp uView Elenment 实现动态二级分类以及二级分类的管理 1. 效果展示1.1 前端显示效果1.2 后台管理一级分类1.3 后台管理二级分类 2. 后端代码2.1 GoodsCategoryController.java2.2.1 GoodsCategoryMapper.java2.2.2 GoodsCategorySonMapper.java2.3.…

蓝桥杯备赛(C/C++组)

README&#xff1a; 本笔记是自己的备考笔记&#xff0c;按照官网提纲进行复习&#xff01;适合有基础&#xff0c;复习用。 一、总考点 试题考查选手解决实际问题的能力&#xff0c;对于结果填空题&#xff0c;选手可以使用手算、软件、编程等方法解决&#xff0c;对于编程大…

Laravel 11入门:使用ServBay打造高效开发环境

Laravel 11发布&#xff0c;改进了不少功能。 它引入了更加流畅的应用结构、每秒限速、健康路由等特性。 此外&#xff0c;Laravel还推出了第一方可扩展的WebSocket服务器Laravel Reverb&#xff0c;为你的应用提供强大的实时功能。 在今天的指南中&#xff0c;我将设置一个…

OSPF中配置VLAN通信(单臂路由)

OSPF中配置VLAN通信&#xff08;单臂路由&#xff09; 单臂路由&#xff08;One-Arm Routing&#xff09;是一种网络路由配置方式&#xff0c;常用于解决网络中的特定问题。在传统的网络架构中&#xff0c;路由器通常需要连接到多个子网或网络段&#xff0c;每个子网都需要一个…

项目管理工具——使用甘特图制定项目计划的详细步骤

甘特图是一种直观的项目管理工具&#xff0c;它有助于我们清晰地展示任务安排、时间管理和项目的进度。以下是使用甘特图制定项目计划的详细步骤&#xff1a; 1、创建项目&#xff1a;首先&#xff0c;在进度猫中创建新的项目&#xff0c;并设置项目的时间、工作日等参数。根据…

test4132

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

14届蓝桥杯 C/C++ B组 T6 岛屿个数 (BFS,FloodFill,填色)

首先拿到这道题不要想着去直接判断环里面的岛屿&#xff0c;这样太困难了&#xff0c;我们可以使用之前做过的题的经验&#xff0c;在输入加入一圈海水&#xff0c;然后从(0,0)点开始BFS&#xff0c;这里进行八向搜索&#xff0c;搜到的0全部都染色成2&#xff0c;假如2能够蔓延…

GEE数据集——巴基斯坦国家级土壤侵蚀数据集(2005 年和 2015 年)

简介 巴基斯坦国家级土壤侵蚀数据集&#xff08;2005 年和 2015 年&#xff09; 该数据集采用修订的通用土壤流失方程 (RUSLE)&#xff0c;并考虑了六个关键影响因素&#xff1a;降雨侵蚀率 (R)、土壤可侵蚀性 (K)、坡长 (L)、坡陡 (S)、覆盖管理 (C) 和保护措施 (P)&#xff…

机器人瓶胚检测工作站(H3U脉冲轴控制)

1、变量定义 2、程序监控1 2、 程序监控2 3、程序监控3 机器人输送料和机构的动作安全尤为重要&#xff0c;下面我们讨论下安全联锁控制逻辑

C++设计模式|0.前言

1.什么是设计模式&#xff1f; 简答来说&#xff0c;设计模式就是一套好用的代码经验总结&#xff0c;也就是怎么写好代码的方法论。使用设计模式是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。 2.设计模式的分类 设计模式可以分为三类&#xff1a;创建型、…

iOS开发如何更改xcode中的Apple ID

在Xcode中更改Apple ID是一项常见的任务&#xff0c;尤其是当你需要切换到另一个开发者账号或者团队时。下面是一个简单的步骤指南&#xff0c;帮助你更改Xcode中的Apple ID&#xff1a; 步骤一&#xff1a;退出当前的Apple ID 1.打开Xcode应用程序。 2.在菜单栏中&#xff0c;…

Vivado Design Suite中的Routing消息与Intermediate Route结果

在Vivado Design Suite中&#xff0c;优化后的Routing消息和Intermediate Route 结果保存在工程文件中的runs\impl_1中的runme.log文件。 一、Routing消息 当路由器由于拥塞或修复过多的保持时间违规而难以达到时序目标时&#xff0c;Routing消息会提供有用的消息。路由器在努力…

Training - PyTorch Lightning 的 Horovod 策略实践 (all_gather)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/137686312 在 PyTorch Lightning 中使用 Horovod 策略&#xff0c;可以在多个 GPU 上并行训练模型。Horovod 是分布式训练框架&#xff…

手写ArrrayList

需求 自定义的MyArrayList import java.util.Arrays; import java.util.Objects;public class MyArrayList<E> {private Object[] elementData ; // 存储元素的数组private int size; // 记录 的元素个数private static final int DEFAULT_CAPACITY 10; // 默认容量// …