Leetcode刷题2

文章目录

  • 前言
  • 寻找两个正序数组的中位数
    • 1️⃣ 双指针快速排序
    • 2️⃣ 第k小数解法
  • Z 字形变换
    • 1️⃣ 个人解法
    • 2️⃣巧妙解法1
    • 3️⃣巧妙解法2
  • 字符串转换整数 (atoi)
    • 1️⃣ 常规方法
    • 2️⃣ 作弊方法😫
  • 整数转罗马数字
    • 1️⃣ 常规方法:按照给定规则写出判断条件即可
    • 2️⃣ 循环实现
  • 罗马数字转整数
    • 1️⃣ 常规处理
    • 2️⃣ 改进
  • 总结


前言

    算法小白初入leetcode。本文主要记录个人在leetcode上使用python解题的思路和过程,如果有更好、更巧妙的解题方法,欢迎大家在评论区给出代码或思路。🚀
在这里插入图片描述


寻找两个正序数组的中位数

  • 题目描述

在这里插入图片描述

  • 实际上就是对数组排序的问题

1️⃣ 双指针快速排序

  • 定义两个指针 i i i j j j,初始时分别指向两个列表的开头。然后,比较指针所指的元素,将较小的元素添加到结果列表中,并将对应指针向后移动一位。重复这个过程,直到其中一个列表的所有元素都被添加到结果列表中。最后,将另一个列表中剩余的元素添加到结果列表的末尾。具体代码和执行过程可以如下所示:
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:num_12 = []i   = 0j   = 0while i<len(nums1) and j <len(nums2):if    nums1[i] < nums2[j]:num_12.append(nums1[i]) i += 1elif  nums1[i] > nums2[j]:num_12.append(nums2[j])j += 1else:   # 如果两个指针指向的数值相同,重复添加该元素,同时移动两个指针num_12 += [nums1[i],nums2[j]]i += 1j += 1# 若其中一个数组遍历完成了,则将另外一个数组中的剩余元素添加到num_12中 while i<len(nums1):num_12.append(nums1[i])i += 1while j<len(nums2):num_12.append(nums2[j])j += 1if len(num_12)%2 == 0:return (num_12[len(num_12)//2] + num_12[len(num_12)//2 - 1]) / 2else :return num_12[len(num_12)//2]

在这里插入图片描述在这里插入图片描述

2️⃣ 第k小数解法

  • 这个解法是众多题解中非常巧妙的一个,具体原理和算法可以直接看这里:第k小数解法视频详解
  • 算法实现:知道原理后,其实本质就是在不断排除比中位数还要小的那些数,直到找到中位数,所以可以利用递归的方式去实现它。
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:total_length = len(nums1) + len(nums2)if total_length % 2 == 1:# 如果总长度为奇数,则中位数为第 (total_length // 2 + 1) 小的元素return self.findKthElement(nums1, nums2, total_length // 2 + 1)else:# 如果总长度为偶数,则中位数为第 total_length // 2 和第 total_length // 2 + 1 小的元素的平均值left = self.findKthElement(nums1, nums2, total_length // 2)right = self.findKthElement(nums1, nums2, total_length // 2 + 1)return (left + right) / 2def findKthElement(self,nums1, nums2, k):"""nums1: 第一个有序数组nums2: 第二个有序数组k    : 要查找的第 k 小的元素(1-indexed)返回值: 第 k 小的元素"""len1, len2 = len(nums1), len(nums2)# 确保 nums1 是较短的数组if len1 > len2:return self.findKthElement(nums2, nums1, k)# 如果较短数组为空,则直接返回 nums2 中的第 k 个元素if len1 == 0:return nums2[k-1]# 如果 k == 1,则返回两个数组中第一个元素的最小值if k == 1:return min(nums1[0], nums2[0])# 选择 nums1 和 nums2 中的 k//2 个元素,比较这两个元素i = min(len1, k // 2)j = min(len2, k // 2)if nums1[i-1] > nums2[j-1]:# 如果 nums1 中第 i 个元素较大,则说明 nums2 中的前 j 个元素不可能是第 k 小的元素return self.findKthElement(nums1, nums2[j:], k - j)else:# 如果 nums2 中第 j 个元素较大,则说明 nums1 中的前 i 个元素不可能是第 k 小的元素return self.findKthElement(nums1[i:], nums2, k - i)

在这里插入图片描述确实是又快了一些,可惜才击败三十多,想知道更快的解法💡

Z 字形变换

  • 题目描述

在这里插入图片描述

1️⃣ 个人解法

  • 可以发现每一行的字符都与第一行的字符存在关联的,所以只要先确定第一行的元素,后面几行的元素就能确定了。如题目描述中的示例2,第二行字符ALSIG可以认为是第一行字符PIN中每个元素在 s s s中的索引位置向左和右各移动 1 1 1次得到(超出索引位置就舍弃掉),第二行字符YAHR可以认为是第一行字符PIN中每个元素在 s s s中的索引位置向左和右各移动 2 2 2次得到(超出索引位置就舍弃掉),依次类推…
    但是要注意两点:1):最后一行的字符按照这样的处理会导致出现重复,所以需要单独处理;2):如果是下面这种情况,按照这样的处理就会导致末尾RI这两个字符遗漏,所以由第一行字符中最后一个字符确定其他行字符时,需要单独处理。

在这里插入图片描述

class Solution:def convert(self, s: str, numRows: int) -> str:'''思路:先确定第一行和最后一行的元素,后面几行的元素顺序与第一行有关'''if numRows == 1:return sline1       = ''line1_index = []length      = len(s)for i in range(0,length,2*(numRows-1)):line1 += s[i]line1_index.append(i)for i in range(numRows-1):next_line = ''index = []for j in line1_index:if i == numRows-2:    #最后一行作特殊处理if j+numRows-1 < length:next_line += s[j+numRows-1]else:if j-i-1 > 0:next_line += s[j-i-1]if j+i+1 < length:next_line += s[j+i+1]if j == line1_index[-1] and j+2*numRows-3-i < length:next_line += s[j+2*numRows-3-i]line1 += next_linereturn line1

在这里插入图片描述
不过时间效率并不高,有待优化🤦‍♂️

2️⃣巧妙解法1

  • 参考leetcode-wuji3

在这里插入图片描述


class Solution:def convert(self, s: str, numRows: int) -> str:temp = [i for i in range(numRows)]temp += temp[1:-1][::-1]res = [''] * numRowsn = len(s)for i in range(n):res[temp[i%len(temp)]] += s[i]return ''.join(res)

在这里插入图片描述
思路清晰,代码简洁,确实很巧妙!

3️⃣巧妙解法2

  • 使用变量 i i i 表示当前字符的行索引,初始值为 0 0 0;使用变量 f l a g flag flag 表示行索引的变化方向,初始值为 − 1 -1 1。然后遍历原字符串中的每个字符 c c c:将当前字符 c c c 添加到 r e s [ i ] res[i] res[i] 对应的行中。如果当前行索引 i 到达首行或末行,则改变 f l a g flag flag 的方向。最后根据 f l a g flag flag 的方向更新行索引 i i i,这样一来就实现了“Z”字形的逻辑。
class Solution:def convert(self, s: str, numRows: int) -> str:if numRows < 2:return sres = ['' for i in range(numRows)]i , flag = 0,-1for c in s:res[i] += cif i == 0 or i == numRows - 1:flag = -flagi = i + flagreturn ''.join(res)

在这里插入图片描述

字符串转换整数 (atoi)

  • 题目描述:

在这里插入图片描述

1️⃣ 常规方法

  • 按照题目,思路如下:
    • 第一步去掉字符串前面的所有空格;
    • 分类讨论,只保留符合条件的字符:
      • 首字符是-或者+的情况:从第二个字符遍历到最后一个字符,满足条件的字符留下。对于是否保留 0 0 0这个字符,可以通过最终拼接的字符串re的长度来判断,如果等于 0 0 0说明是前置零,直接舍弃,其余情况则保留。对于非数字字符的判断,可以通过 A s c a l l Ascall Ascall码来进行判断。
      • 其他情况:同上处理,只不过从开头遍历到结尾。
    • 将最后拼接的字符串转换成整数并输出。
class Solution:def myAtoi(self, s: str) -> int:s = s.strip()re  = ''if s == '':return 0elif s[0] == '-' or s[0] == '+':i = 1while i <= len(s)-1:if ord(s[i]) < 48 or ord(s[i]) > 57:breakif len(re) == 0  and s[i] == 0:continueelse:re += s[i]i += 1if len(re) == 0:return 0elif s[0] == '-':return max(-int(re),-2**31)else:return min(int(re),2**31-1)else:i = 0while i <= len(s)-1:if ord(s[i]) < 48 or ord(s[i]) > 57:breakif len(re) == 0  and s[i] == 0:continueelse:re += s[i]i += 1if len(re) == 0:return 0else:return min(int(re) , 2**31-1)

在这里插入图片描述

2️⃣ 作弊方法😫

  • 其实Python中的内置函数int可以直接实现这个题目的大部分情况,我们直接拿来使用,然后对于使用不了的情况就用try ... except进行捕捉,然后再使用上面的常规方法。
class Solution:def myAtoi(self, s: str) -> int:try:return max(int(s),-2**31) if '-' in s else min(int(s),2**31-1) except Exception as e:s = s.strip()re  = ''if s == '':return 0elif s[0] == '-' or s[0] == '+':i = 1while i <= len(s)-1:if ord(s[i]) < 48 or ord(s[i]) > 57:breakif len(re) == 0  and s[i] == 0:continueelse:re += s[i]i += 1if len(re) == 0:return 0elif s[0] == '-':return max(-int(re),-2**31)else:return min(int(re),2**31-1)else:i = 0while i <= len(s)-1:if ord(s[i]) < 48 or ord(s[i]) > 57:breakif len(re) == 0  and s[i] == 0:continueelse:re += s[i]i += 1if len(re) == 0:return 0else:return min(int(re) , 2**31-1)            

在这里插入图片描述确实提速了一些hhh

整数转罗马数字

  • 题目描述

在这里插入图片描述

1️⃣ 常规方法:按照给定规则写出判断条件即可

class Solution:def intToRoman(self, num: int) -> str:char_num = {1:'I',5:'V',10:'X',50:'L',100:'C',500:'D',1000:'M',4:'IV',9:'IX',40:'XL',90:'XC',400:'CD',900:'CM'}re = ''while num > 0:if 1000 <= num:re += char_num[1000]num -= 1000elif 900 <= num < 1000:re += char_num[900]num -= 900elif 500 <= num < 900:re += char_num[500]num -= 500  elif 400 <= num < 500:re += char_num[400] num -= 400elif 100 <= num < 400:re += char_num[100]num -= 100elif 90 <= num < 100:re += char_num[90]num -= 90elif 50 <= num < 90:re += char_num[50]num -= 50elif 40 <= num < 50:re += char_num[40]num -= 40elif 10 <= num < 40:re += char_num[10]num -= 10elif 9 <= num < 10:re += char_num[9]num -= 9elif 5 <= num < 9:re += char_num[5]num -= 5elif 4 <= num < 5:re += char_num[4]num -= 4elif 1 <= num < 4:re += char_num[1]num -= 1return re

在这里插入图片描述

2️⃣ 循环实现

  • 将上面判断改成循环的方式实现
class Solution:def intToRoman(self, num: int) -> str:char_num = {1000:'M', 900:'CM', 500:'D', 400:'CD', 100:'C', 90:'XC', 50:'L', 40:'XL', 10:'X', 9:'IX', 5:'V', 4:'IV', 1:'I'}re = ''for i in char_num.keys():if num // i != 0:re += char_num[i] * (num//i)num = num % i return re

在这里插入图片描述
不过速度变慢了一些

罗马数字转整数

  • 题目描述(上面一题的相反处理)

在这里插入图片描述

1️⃣ 常规处理

  • 先将字符串中特殊的 6 6 6种罗马数字挑选出来转换成整数,然后再将剩下的罗马单个字符一一转换成数字即可。
class Solution:def romanToInt(self, s: str) -> int:dict1 = {'I': 1,'V': 5,'X': 10,'L': 50,'C': 100,'D': 500,'M': 1000}dict2 = {'IV': 4,'IX': 9,'XL': 40,'XC': 90,'CD': 400,'CM': 900}result = 0for i in dict2.keys():if i in s:result += dict2[i]s       = s.replace(i,'')for i in s:result += dict1[i]return result

在这里插入图片描述

2️⃣ 改进

  • 上面算法需要遍历两次字符串,时间复杂度为 O ( 2 n ) \mathcal{O(2n)} O(2n),其实只需要遍历一次就行,时间复杂度变成 O ( n ) \mathcal{O(n)} O(n)
class Solution:def romanToInt(self, s: str) -> int:dict1 = {'I': 1,'V': 5,'X': 10,'L': 50,'C': 100,'D': 500,'M': 1000}dict2 = {'IV': 4,'IX': 9,'XL': 40,'XC': 90,'CD': 400,'CM': 900}result = 0while len(s) >= 1:if len(s) == 1:result += dict1[s[0]]s = ''elif dict1[s[0]] < dict1[s[1]]:result += dict2[s[0:2]]s = s[2:]else:result += dict1[s[0]]s = s[1:]return result   

在这里插入图片描述

总结

算法小白初入leetcode,期待给出更精妙的算法🚀🚀🚀

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

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

相关文章

WSL调用docker

WSL&#xff08;windows subsystem linux&#xff09;是window系统的原生linux子系统&#xff0c;用于代码开发很方便。 希望在wsl里面运行docker&#xff0c;首先要安装docker在WSL中使用&#xff0c;大部分人的第一想法肯定是用以下命令行安装&#xff08;个人不推荐&#x…

java的unsafe

在Java中&#xff0c;sun.misc.Unsafe 是一个强大且危险的类&#xff0c;它提供了一些直接操作内存、对象和线程的底层功能。这个类通常不鼓励普通开发者使用&#xff0c;因为它绕过了Java语言的一些安全性和内存管理机制&#xff0c;可能会导致难以追踪的错误和安全漏洞。 Un…

2.go环境配置与开发工具选择

go 环境配置 下载安装包 官网(https://go.dev/dl/) 下载地址(国内)(https://golang.google.cn/dl/) 根据自己的操作系统选择下载即可 下载后安装 记住地址 比如&#xff1a; D:\work\devtool\go 配置系统环境变量 PATH 指向 go 的安装 bin 目录 比如&#xff1a; D:\work…

若依前端vue实现 输入框下拉选择加搜索用户

探索代码以及详细的注解 <template><div><el-select v-model"selectedUserId" filterable placeholder"选择用户" change"handleChange"><el-optionv-for"user in filteredUsers":key"user.userId":l…

集合框框框地架

这一次来介绍一下常用的集合&#xff1a; 首先是两种集合的《家庭系谱图》&#xff1a; 接下来介绍一下集合的种类&#xff1a; Collection Set SetTreeSet&#xff1a;基于红⿊树实现&#xff0c;⽀持有序性操作&#xff0c;例如&#xff1a;根据⼀个范围查找元素的操作。但…

Unity实现TableView

基于Scrollview封装的TableView&#xff0c;实现对视野外的Cell回收利用&#xff0c;减少创建Cell的开销。 核心逻辑如下&#xff1a; /***************************************动态使用cell核心逻辑开始 **************************************///计算所有cell的坐标信息 …

利用java8 的 CompletableFuture 优化 Flink 程序,性能提升 50%

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

AI图书推荐:用100个ChatGPT提示词掌握Python编程

《用100个ChatGPT提示词掌握Python编程》&#xff08;ChatGPT:Your Python Coach Mastering the Essentials in 100 Prompts&#xff09; 塞尔吉奥罗哈斯-加莱亚诺&#xff08;Sergio Rojas-Galeano&#xff09;是一位热情的计算机科学家&#xff0c;对人工智能、机器学习、进化…

C++中获取int最大与最小值(补)

上文中&#xff0c;我们学习了C中获取int最大与最小值的两种方法&#xff1a;C库和移位运算&#xff0c;这篇文章将解决在移位运算中遇到的各种报错&#xff0c;并提出一种新的生成int最值的方法 上文链接&#xff1a;http://t.csdnimg.cn/cn7Ad 移位运算取最值常见报错 Dev…

汇编语言(STC89C52)

指令是计算机计算CPU根据人的意图来执行某种操作的命令。一台计算机所执行的全部指令的集合&#xff0c;称为这个CPU的指令系统。而想要使计算机按照人们的要求完成一项工作&#xff0c;就必须让CPU按顺序执行预设的操作&#xff0c;即逐条执行人们编写的指令。这种按照人民要求…

C++ 写的_string类,兼容std::string, MFC CString和 C# 的string

代码例子&#xff1a; using namespace lf; int main() { CString s1 _t("http://www.csdn.net"); _string s2 s1; CString s3 s2; _pcn(s1); _pcn(s2); _pcn(s3); return 0; } 输出&#xff1a; _Str.h /***************************************…

网创教程:WordPress插件网创自动采集并发布

网创教程&#xff1a;WordPress插件网创自动采集并发布 使用插件注意事项&#xff1a; 如果遇到404错误&#xff0c;请先检查并调整网站的伪静态设置&#xff0c;这是最常见的问题。需要定制化服务&#xff0c;请随时联系我。 本次更新内容 我们进行了多项更新和优化&#x…

深入解析kube-scheduler的算法自定义插件

目录 ​编辑 一、问题引入 二、自定义步骤 三、最佳实践考虑 一、问题引入 当涉及到 Kubernetes 集群的调度和资源分配时&#xff0c;kube-scheduler 是一个关键组件。kube-scheduler 负责根据集群的调度策略&#xff0c;将 Pod 分配到适当的节点上。kube-scheduler 默认使…

pyqt6入门案例

效果预览 hello.ui <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Dialog</class><widget class"QDialog" name"Dialog"><property name"geometry"><…

android studio接入facebook踩坑1

今天在接入facebook第三方登录的时候&#xff0c;点击登录按钮&#xff0c;APP闪退&#xff0c;并报错 java.lang.RuntimeException Failure delivering result ResultInfo{whonull,request64206,result-1} 新文章链接https://lengmo714.top/facebook1.html 如下图&#xff1a;…

html多节点生成图片并导出zip包

html多节点生成图片并导出zip包 背景 在做项目时遇到一个要将html节点展示的图片列表统一导出为zip包的需求。 难点 将html节点生成图片将多张图片加入zip包中&#xff0c;然后下载 解决html生成图片问题 参考html截图的思路使用 pnpm add html-to-image如何将图片资源生成z…

鸿蒙OS开发:【一次开发,多端部署】(多设备自适应能力)简单介绍

多设备自适应能力 介绍 本示例是《一次开发&#xff0c;多端部署》的配套示例代码&#xff0c;展示了[页面开发的一多能力]&#xff0c;包括自适应布局、响应式布局、典型布局场景以及资源文件使用。 名称简介 开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhe…

数据可视化技术头歌测试合集

努力是为了不平庸~ 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰 目录 时间趋势可视化-柱形图 第1关&#xff1a;“大胃王”比赛数据柱形图绘制——绘制柱形图的基本步骤 任务描述 相关知识 观察和处理数据 绘…

Linux中gcc/g++的基本使用

目录 gcc/g的使用gcc/g是如何生成可执行文件的预处理编译汇编链接 库.o文件是如何与库链接的&#xff1f; debug版本和release版本 gcc/g的使用 在windows中&#xff0c;我们在VS中编写好了代码之后就可以直接在VS中对源码进行编译等操作后运行 而在Linux下&#xff0c;我们可…

LeetCode 279 —— 完全平方数

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 此图利用动态规划进行求解&#xff0c;首先&#xff0c;我们求出小于 n n n 的所有完全平方数&#xff0c;存放在数组 squareNums 中。 定义 dp[n] 为和为 n n n 的完全平方数的最小数量&#xff0c;那么有状态…