【PythonCode】力扣Leetcode16~20题Python版

【PythonCode】力扣Leetcode16~20题Python版

前言

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

16. 最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

示例 1:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入:nums = [0,0,0], target = 1
输出:0
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104

代码实现:

class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:nums.sort()n = len(nums)if n == 3 or target <= nums[0] + nums[1] + nums[2]:return nums[0] + nums[1] + nums[2]if target >= nums[n-1] + nums[n-2] + nums[n-3]:return nums[n-1] + nums[n-2] + nums[n-3]result = nums[0] + nums[1] + nums[2]for i in range(n - 2):if i > 0 and nums[i] == nums[i - 1]:continuej, k = i + 1, n - 1while j < k:if abs(nums[i] + nums[j] + nums[k] - target) < abs(result - target):result = nums[i] + nums[j] + nums[k]if result == target:return resultif nums[i] + nums[j] + nums[k] > target:k -= 1else:j += 1return result

解题思路:本题是力扣15题《三数之和》的变化版,第15题是三个数之和为0,本题是三个数之和最接近目标值target,所以解题思路相似。

先将数组排序,首先分析特殊情况,如果数组只有三个数,那最接近目标值的三数之和必然就是三个数相加。因为将数组做了排序,如果目标值小于前三个数之和,那最接近目标值的三数之和就是前三个数之和,同理如果目标值大于最大的三个数之和,那最接近目标值的三数之和就是最后三个数之和。

对于一般的情况,首先先遍历获取第一个数,然后再用双指针的方式取第二个数和第三个数,将三数之和初始化为前三个数之和。使用双指针时,第二个数从第一个数的后一个开始取,第三个数从数组的最后一个数开始取,如果三数之和大于目标值,则第三个数的指针前移,如果三数之和小于目标值,则第二个数的指针后移,如果三数之和等于目标值直接返回。在遍历过程中不断更新三数之和,当找到与目标值相等或遍历完数组之后,程序结束。

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

示例 1:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:
输入:digits = “”
输出:[]
示例 3:
输入:digits = “2”
输出:[“a”,“b”,“c”]
提示:
0 <= digits.length <= 4
digits[i] 是范围 [‘2’, ‘9’] 的一个数字。

代码实现:

class Solution:def letterCombinations(self, digits: str) -> List[str]:if digits == '':return []conversion = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}def backtrack(index):if index == len(digits):result.append("".join(temp))else:digit = digits[index]for x in conversion[digit]:temp.append(x)backtrack(index + 1)temp.pop()result = []temp = []backtrack(0)return result    

解题思路:本题需要将字符串中每个数字对应的字母组合在一起,所以要遍历每一个数字对应的多个字母,然而数字的个数是0到4,不知道是几层遍历,不好求解。这里可以用回溯法,回溯法刚好可以穷举解空间的所有可能。参考:循序渐进,搞懂什么是回溯算法

按照回溯法的求解步骤,先定义回溯的解空间,本题是求数字对应的所有字母组合,所以结果是一个数组。回溯时,搜索树是一个高度最高为4的搜索树,深度优先遍历时在每一层取一个字母。在每次遍历到搜索树的叶结点时,会得到一种组合,将组合保存到求解的数组中,直到遍历完整个搜索树。

结合代码,首先定义好数字和字母的映射关系,初始化求解的结果数组result,回溯时的字母组合数组temp。然后定义回溯函数backtrack(),在回溯函数中,如果遍历到叶结点,就找到一种组合,所以当遍历的高度等于搜索树的高度时,要把当前的字母组合temp保存到result中,如果没有到叶结点,就在当前的结点取一个字母添加到temp中,往回回溯时,将上一个添加的字母从temp中移除,也就是将temp中的最后一个字母移除。最后调用回溯函数backtrack(),从高度0开始,从根结点开始遍历搜索树。

特殊情况,digits如果长度为0,此时不存在字母组合,直接返回空数组。

18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。

示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109

代码实现:

class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:if len(nums) < 4:return []nums.sort()result = []for i in range(len(nums) - 3):if i > 0 and nums[i] == nums[i - 1]:continuefor j in range(i + 1, len(nums) - 2):if j > i + 1 and nums[j] == nums[j - 1]:continuex = j + 1y = len(nums) - 1while x < y:if x < y and nums[i] + nums[j] + nums[x] + nums[y] < target:x += 1while nums[x] == nums[x-1] and x < y:x += 1if x < y and nums[i] + nums[j] + nums[x] + nums[y] > target:y -= 1while nums[y] == nums[y+1] and x < y:y -= 1if x < y and nums[i] + nums[j] + nums[x] + nums[y] == target:result.append([nums[i], nums[j], nums[x], nums[y]])x += 1while nums[x] == nums[x-1] and x < y:x += 1return result

解题思路:四数之和是三数之和的升级版,数字多了一个,但是整体解题思路不变,只是时间复杂度更大,情况也更复杂了。解题方法是嵌套遍历前两个数,后两个数用双指针。

先将数组排序,首先遍历取第一个数和第二个数,第一个数可以从数组第一个数遍历到数组的倒数第四个数,第二个数可以从第一个数的后一个数遍历到数组的倒数第三个数。然后用双指针取第三个数和第四个数,第三个数从第二个数的后一个数开始取,第四个数从数组最后一个数开始取。遍历第一个数和第二个数时,如果当前数值与前一个数值相等,则跳过(剪枝)。

取到四个数后,将四数之和与目标值比较,如果四数之和小于目标值,则第三个数的指针右移,如果四数之和大于目标值,则第四个数的指针左移,如果四数之和等于目标值,则找到一种组合,将当前组合保存到结果中。这里有两个注意点,一是找到一种组合后,不能跳过当前遍历,因为如果当前的四数之和等于0,第三个数变大,同时第四个数变小,可能还有其他组合的和也等于0,所以找到一种组合后,将第三个数的指针右移继续找。二是在移动第三个数或第四个数的指针时,如果当前的值等于上一个数的值,应继续移动指针,否则会将重复的组合添加到结果中,并且可能还有连续几个值相等的情况,所以代码是在while循环中移动指针。这里虽然多了一层循环,只有当数组中连续多个值相等才会跑到while循环的代码,对时间复杂度基本没有影响。

19. 删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

在这里插入图片描述

示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

代码实现:

class Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:prev = ListNode(0, head)fast, slow = prev, prevfor i in range(n):  fast = fast.nextwhile fast.next:fast = fast.next  slow = slow.nextslow.next = slow.next.nextreturn prev.next

解题思路:要删除链表中的倒数第N个结点,首先要找到目标结点的前一个结点,也就是倒数第 n+1 个结点,修改前一个结点的 next 指针,让它指向目标结点的下一个结点,即倒数第 n-1 个结点。参考:Python实现单向链表

要找到链表的倒数第 n+1 个结点,可以先求出链表的长度 L ,第 L-n 个结点就是倒数 n+1 个结点。这样需要遍历两次链表,第一次求长度,第二次找倒数 n+1 个结点。还有一种更好的方法是使用双指针,这里的双指针和前面求三数之和时的用法有点差异,也叫快慢指针,两个指针的移动方向一样,一个在前一个在后。

在开始使用指针前,因为要找倒数第 n+1 个结点,假如 n 等于链表长度,也就是要删除链表的头结点,此时不存在倒数第 n+1 个结点,所以需要先对链表做一个特殊处理,在链表前加一个前置节点,使得双指针具有一般性。

在初始状态,让两个指针都指向链表的前置节点,然后让快的一个指针先向前移动 n 个结点,然后两个指针以相同的速度向后移动,直到快指针移动到链表的末尾,此时慢指针指向的节点就是倒数第 n+1 个结点。此时,将倒数第 n+1个结点的 next 指向倒数第 n-1 个结点,即可从链表中删除倒数第 n 个结点。

题目要求返回链表的头,因为在链表的前面加了一个前置节点,所以链表的头是前置节点的下一个节点,即 prev.next 。

20. 有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
提示:
1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成

代码实现:

class Solution:def isValid(self, s: str) -> bool:dic = {'(': ')', '{': '}', '[': ']'}stack = []for c in s:if c in dic:stack.append(c)elif stack and dic[stack[-1]] == c:stack.pop()else:return Falsereturn not stack

解题思路:本题中,有效的字符串中括号是成对的,并且是按规则闭合的(可以嵌套),三种类型的括号都是先有左括号再有右括号,这种成对的判断刚好可以对应栈的入栈和出栈,所以可以用栈来实现本题。参考:Python实现栈

先初始化一个字典,维护左括号与右括号的关系,并初始化一个空栈(代码中这个栈用列表、字符串等都行)。遍历字符串s,如果当前的符号是关系字典中的key,则入栈,如果栈非空,并且当前的符号与栈顶的符号对应,能组成一组闭合的括号,则将栈顶的符号出栈。如果是其他情况(栈为空时遇到右括号、右括号与当前栈顶的左括号类型不一样不能闭合),则直接返回False。

遍历完字符串s,如果栈是空的,则表示字符串s有效,所有括号都能按规则闭合,如果栈非空,则表示字符串s无效,还剩余未闭合的括号。


相关阅读

【PythonCode】力扣Leetcode11~15题Python版

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

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

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

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

相关文章

React【Day4下+5】

环境搭建 使用CRA创建项目&#xff0c;并安装必要依赖&#xff0c;包括下列基础包 Redux状态管理 - reduxjs/toolkit 、 react-redux路由 - react-router-dom时间处理 - dayjsclass类名处理 - classnames移动端组件库 - antd-mobile请求插件 - axios 配置别名路径 1. 背景知识…

【Linux 进程间通信】管道

文章目录 1.System V 标准介绍2.进程间通信的方式&#xff1f;3.管道&#xff08;匿名管道&#xff09; 1.System V 标准介绍 ①&#x1f34e; System V 实际上就是一个标准&#xff08;“ 行业领头羊制定出来的专利 " &#xff09; 2.进程间通信的方式&#xff1f; …

linux下摄像头设置固定的设备名

目录 2.热插拔udev机制 3.设置udev的规则 1.查看usb ID 2. 查看usb设备的信息 3.编译规则 4.拓展 1.问题的出现 通过我之前的文章配置完摄像头的开机自启动之后我们会发现有的时候会出现启动不了的情况&#xff0c;通过实验我发现是摄像头的设备名发生了改变&#xff0c;…

ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…

开源数据集分享——猫脸码客

开源数据集分享&#xff0c;让数据更自由流通——猫脸码客带你走进数据的新世界 在数字化时代的浪潮中&#xff0c;数据已经成为推动社会进步的重要力量。然而&#xff0c;数据的获取与利用往往受到种种限制&#xff0c;使得许多有价值的信息难以被充分挖掘。幸运的是&#xf…

适配器模式【结构型模式C++】

1.概述 适配器模式是一种结构型设计模式&#xff0c; 又称为变压器模式、包装模式&#xff08;Wrapper&#xff09; 将一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 2.结构 Target&#xff1a;适配…

Leetcode算法训练日记 | day31

专题九 贪心算法 一、分发饼干 1.题目 Leetcode&#xff1a;第 455 题 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的…

【算法一则】矩阵置零 【矩阵】【空间复用】

题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&#xff1a; …

冰达ROS机器人快速使用指南

欢迎来到《冰达ROS机器人极简使用指南》 Q&#xff1a;这份教程适合谁&#xff1f; A&#xff1a;适合完全0基础新手&#xff0c;需要快速跑起来机器人的基本功能。也适合技术大佬需要快速的了解冰达ROS机器人的使用方法。 Q&#xff1a;这份教程内容很少&#xff0c;是不是…

机器学习基本流程

Jupyter Notebook 代码连接&#xff1a; machine_learning_demo machine_learning_ensembles Step 1: Imports and Configuration import pandas as pd import numpy as np import copy import json import pickle import joblib import lightgbm as lgb import optuna impor…

国产数据库实践:亚信安慧AntDB在DTC 2024展示创新实力

4月12至13日&#xff0c;我国数据库行业最具影响力的活动之一——第十三届『数据技术嘉年华』(DTC 2024) 在京成功举办&#xff0c;业内众多专家学者、技术领袖、各行业客户和实力厂商均到场参会。亚信安慧AntDB数据库总架构师洪建辉受邀参与“数据库一体化”专题论坛&#xff…

Stylus精讲:网页设计新境界【写作AI一键生成】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

《HCIP-openEuler实验指导手册》1.1Apache安装与测试

一、安装httpd 查看软件仓库中apache版本列表 dnf provides http 安装apache dnf install -y httpd 二、启动http并测试 查看apache版本号 httpd -v 检查配置文件是否正确 httpd -t 启动并设置为开机启动 systemctl enable httpd --now 或 systemctl enable httpd syst…

Android--ConnectivityManager使用

一、前言 Android10之后官方废弃了通过WifiManager连接WIFI的方式&#xff0c;现在要使用ConnectivityManager连接WIFI 二、连接WIFI public class MainActivity extends AppCompatActivity {private static final String TAG"lkx";Overrideprotected void onCrea…

yolov8实战第七天——pyqt5-yolov8实现车牌识别系统(参考论文(约7000字)+环境配置+完整部署代码+代码使用说明+训练好的模型)

基于 pyqt5-yolov8实现车牌识别系统,包括图片车牌识别,视频车牌识别,视频流车牌识别。 效果展示(图片检测,检测到的内容添加到历史记录): 效果展示(视频检测,视频车辆只会添加一条记录,下文更多实际应用中的优化策略): 基于YOLOv8和PyQt5的车牌识别系统设计与…

day60 接雨水 柱状图中的最大矩形

题目1&#xff1a;42 接雨水 题目链接&#xff1a;42 接雨水 题意 n个宽度为1高度不一致的柱子排列&#xff0c;可以接多少雨水 找寻当前柱子的左面第一个比该柱子高的(栈顶的下一个元素)&#xff0c;右面第一个比该柱子高的(当前遍历的元素)&#xff0c;作差 得到宽度&…

在React项目中试用Tailwind

TailwindCSS TailwindCSS 是一个套 CSS 的工具类&#xff0c;把常用的功能都进行了定义&#xff0c;下面是一个官网的例子&#xff0c;可以看到Tailwind对一元页面素写了很多类&#xff0c;日常开发中只要定义一两个类就可以搞定类似的功能了。这里写了这么多 p-6 max-w-sm mx…

java导出数据到excel表中

java导出数据到excel表中 环境说明项目结构1.controller层2.service层3.实现层4.工具类&#xff1a;ExcelUtil.java5.ProductModel.java类 使用的Maven依赖postman请求展示&#xff0c;返回内容需要前端接收浏览器接收说明&#xff08;如果下载下来的为zip类型&#xff0c;记得…

C语言读取数据检索存档《C语言程序设计》·第6章·用数组处理批量数据

C数组使用 添加链接描述 C语言读取数据检索存档 1 添加链接描述 2 添加链接描述 3 添加链接描述 4 添加链接描述 5 添加链接描述 6 添加链接描述 7 matlab转C 添加链接描述

【从浅学到熟知Linux】基础IO第三弹=>文件系统介绍、软链接与硬链接(含磁盘结构、文件系统存储原理、软硬链接的创建、原理及应用详解)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 理解文件系统物理角度认识磁盘逻辑角度认识磁盘磁盘寻址磁盘中的寄存器 磁盘存储管理 软链接与硬链接软链接…