每日一题——Python代码实现力扣1. 两数之和(举一反三+思想解读+逐步优化)五千字好文

news2025/1/14 18:04:58


一个认为一切根源都是“自己不够强”的INTJ

个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数

Python-3.12.0文档解读

目录

菜鸡写法

代码分析

时间复杂度分析

空间复杂度分析

改进建议

我要更强

方法1: 使用哈希表(字典)

方法2: 排序和双指针

方法3: 使用集合(仅适用于特殊情况)

哲学和编程思想

1. 空间与时间的权衡(Space-Time Tradeoff)

2. 分治法(Divide and Conquer)

3. 迭代与递归

4. 数据结构的选择

5. 算法优化

6. 抽象与具体化

7. 代码的可读性与效率

举一反三

1. 空间与时间的权衡

2. 分治法

3. 迭代与递归

4. 数据结构的选择

5. 算法优化

6. 抽象与具体化

7. 代码的可读性与效率


题目链接:https://leetcode.cn/problems/two-sum/description/

菜鸡写法

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        len_nums=len(nums)
        for i in range(len_nums):
            for j in range(len_nums):
                if i==j:
                    continue
                if nums[i]+nums[j]==target:
                    return [i,j]

这段代码是一个Python类Solution的方法twoSum,其目的是在给定的整数列表nums中找到两个数,使得这两个数的和等于给定的目标值target。如果找到这样的两个数,方法返回一个包含这两个数索引的列表;如果没有找到,理论上应该返回一个特定的值(如None或[-1, -1]),但这段代码在找到解后立即返回,没有处理无解的情况。

代码分析

  1. 循环结构:代码使用了两个嵌套的循环来遍历列表nums。外层循环从第一个元素遍历到最后一个元素,内层循环同样从第一个元素遍历到最后一个元素。
  2. 条件判断:在内层循环中,首先通过if i==j来跳过自身与自身相加的情况,然后通过if nums[i]+nums[j]==target来检查两个数的和是否等于目标值。
  3. 返回结果:一旦找到满足条件的两个数,立即返回它们的索引。

时间复杂度分析

由于使用了两个嵌套的循环,每个循环都遍历整个列表,因此时间复杂度为O(n^2),其中n是列表nums的长度。这是因为对于列表中的每一个元素,都需要与其他所有元素进行比较。

空间复杂度分析

空间复杂度为O(1),因为除了输入的列表和几个变量(如索引和循环控制变量)外,没有使用额外的数据结构来存储信息。所有的操作都是基于原始列表进行的。

改进建议

这段代码的时间复杂度较高,可以通过使用哈希表(在Python中为字典)来优化。使用哈希表可以在一次遍历中找到解,时间复杂度可以降低到O(n)。


我要更强

方法1: 使用哈希表(字典)

这是最常见的优化方法,通过使用哈希表来存储元素及其索引,可以在一次遍历中找到解。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        num_to_index = {}
        for i, num in enumerate(nums):
            complement = target - num
            if complement in num_to_index:
                return [num_to_index[complement], i]
            num_to_index[num] = i
        return None  # 如果没有找到,返回None

时间复杂度: O(n),其中n是列表nums的长度。我们只遍历了一次列表。 空间复杂度: O(n),因为我们需要一个哈希表来存储元素及其索引。

方法2: 排序和双指针

这种方法首先对数组进行排序,然后使用两个指针分别从头部和尾部开始移动,直到找到解。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        sorted_indices = sorted(range(len(nums)), key=lambda x: nums[x])
        left, right = 0, len(nums) - 1
        while left < right:
            sum_ = nums[sorted_indices[left]] + nums[sorted_indices[right]]
            if sum_ == target:
                return [sorted_indices[left], sorted_indices[right]]
            elif sum_ < target:
                left += 1
            else:
                right -= 1
        return None  # 如果没有找到,返回None

时间复杂度: O(n log n),主要来自于排序操作。 空间复杂度: O(n),因为我们需要一个额外的列表来存储排序后的索引。

方法3: 使用集合(仅适用于特殊情况)

如果数组中的数字都是正数且范围有限,我们可以使用集合来存储所有可能的差值,然后检查这些差值是否存在于数组中。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        if all(isinstance(num, int) and num >= 0 for num in nums):
            possible_diffs = set()
            for num in nums:
                if num in possible_diffs:
                    return [target - num, num]
                possible_diffs.add(target - num)
        return None  # 如果没有找到,返回None

时间复杂度: O(n),遍历了一次数组。 空间复杂度: O(n),因为需要一个集合来存储所有可能的差值。

这些方法提供了不同的优化策略,可以根据具体问题的要求和限制选择最合适的方法。


哲学和编程思想

这些优化方法体现了多种哲学和编程思想,包括但不限于:

1. 空间与时间的权衡(Space-Time Tradeoff)

  • 哈希表方法:通过使用额外的空间(哈希表)来存储已经遍历过的元素及其索引,减少了时间复杂度。这是一种典型的空间换时间的策略。
  • 排序和双指针方法:虽然这种方法需要额外的空间来存储排序后的索引,但它通过排序和双指针的策略,有效地减少了查找匹配对的时间。

2. 分治法(Divide and Conquer)

  • 排序和双指针方法:这种方法通过将数组分为两部分,并从两端向中间移动指针,利用了分治的思想。通过比较和调整指针位置,逐步缩小搜索范围,直到找到解。

3. 迭代与递归

  • 所有方法:这些方法都使用了迭代而非递归,通过循环结构来遍历数组或集合,这是编程中常用的控制结构,可以有效地处理大量数据。

4. 数据结构的选择

  • 哈希表方法:选择哈希表作为数据结构是因为它提供了快速的查找操作(平均时间复杂度为O(1)),这对于需要在遍历过程中快速查找元素的情况非常有效。
  • 排序和双指针方法:使用排序后的索引列表和双指针,利用了排序后数组的特性,即相邻元素的顺序关系,来加速查找过程。

5. 算法优化

  • 哈希表方法:通过在遍历过程中即时检查目标值的补数是否已存在于哈希表中,避免了不必要的重复计算。
  • 排序和双指针方法:通过排序和双指针的策略,避免了遍历整个数组,减少了比较的次数。

6. 抽象与具体化

  • 所有方法:这些方法都体现了从具体问题(找到两个数使其和为目标值)到抽象算法(使用哈希表、排序和双指针等)的转换,这是编程中解决问题的关键步骤。

7. 代码的可读性与效率

  • 所有方法:在编写代码时,不仅要考虑算法的效率,还要考虑代码的可读性和维护性。这些方法都尽量保持代码简洁明了,易于理解和修改。

通过这些方法,可以看到编程不仅仅是技术操作,更是一种结合了逻辑思维、数学原理和工程实践的艺术。每种方法都体现了对问题本质的深刻理解和创新思维的应用。


举一反三

理解并应用这些哲学和编程思想可以帮助在面对新的编程问题时举一反三。以下是一些技巧和建议:

1. 空间与时间的权衡

  • 分析问题:在解决问题时,首先分析是否可以通过增加空间复杂度来减少时间复杂度。例如,使用缓存或哈希表来存储中间结果,以避免重复计算。
  • 优化策略:在时间和空间之间找到平衡点。如果内存不是问题,考虑使用更多的空间来加速程序运行。

2. 分治法

  • 分解问题:将复杂问题分解为更小的、易于管理的部分。例如,在处理大数据集时,可以将数据集分成几个部分,分别处理后再合并结果。
  • 递归应用:对于可以自然分解为子问题的问题,考虑使用递归算法。确保理解递归的终止条件和如何组合子问题的解。

3. 迭代与递归

  • 选择合适的控制结构:根据问题的性质选择迭代或递归。迭代通常更高效,而递归可以使代码更简洁和直观。
  • 优化递归:如果递归导致性能问题,考虑将其转换为迭代形式,或者使用尾递归优化。

4. 数据结构的选择

  • 了解数据结构:熟悉不同数据结构的优缺点,如数组、链表、栈、队列、树、图、哈希表等。
  • 选择合适的数据结构:根据问题的需求选择最合适的数据结构。例如,如果需要频繁查找,哈希表可能是一个好选择。

5. 算法优化

  • 预处理数据:如果可能,对数据进行预处理,如排序,以加速后续的查找或比较操作。
  • 避免不必要的计算:在循环中,确保不会重复计算相同的结果。使用缓存或记忆化技术存储中间结果。

6. 抽象与具体化

  • 抽象问题:将具体问题抽象为更一般的模型,这有助于找到通用的解决方案。
  • 具体化解决方案:在找到抽象解决方案后,将其具体化以适应特定问题的细节。

7. 代码的可读性与效率

  • 编写清晰代码:始终编写清晰、有条理的代码,即使这可能需要更多的代码行。清晰的代码更容易维护和调试。
  • 性能优化:在确保代码可读性的同时,寻找提高性能的机会。使用性能分析工具来识别瓶颈。

通过实践这些技巧,将能够更好地理解问题的本质,并开发出既高效又易于理解的解决方案。记住,编程是一个不断学习和实践的过程,通过不断的练习和挑战,编程技能将得到显著提升。


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

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

相关文章

项目训练营第四天

项目训练营第四天 前端部分修改 前端用的是WebStorm和Ant Design Pro框架 Ant Design Pro是比较流行的一个前端登陆、注册、管理框架&#xff0c;能帮我们快速实现前端界面的开发 效果大致如图 使用起来也极为方便&#xff0c;首先在WebStorm 控制台中输入如下命令 # 使用…

Linux的基本指令第二篇

1.cat - 查看文件 语法&#xff1a;cat [选项] [文件] 功能&#xff1a; 查看目标文件的内容 -b 对非空输出行编号 -n对输出的所有行编号 -s不输出多行空行 现有一个文件test.c cat -n test.c cat -b test.c cat -s test.c 创建一个新文件 加入源文件的内容 || …

力扣每日一题 6/23 字符串/模拟

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 520.检测大写字母【简单】 题目&#xff1a; 我们定义&#xff0c;在以下…

飞行堡垒系列_键盘灯开关

飞行堡垒系列键盘灯可以通过键盘上的"Fn 方向键"控制 演示机型品牌型号&#xff1a;飞行堡垒8 系统版本&#xff1a;Windows 11 飞行堡垒键盘灯可通过键盘上的"Fn方向键"控制。 " Fn 下方向键 "为减弱键盘灯光&#xff0c;多按几次键盘灯就可…

软考初级网络管理员__软件单选题

1.在Excel 中&#xff0c;设单元格F1的值为56.323&#xff0c;若在单元格F2中输入公式"TEXT(F1,"&#xffe5;0.00”)”&#xff0c;则单元格F2的值为()。 &#xffe5;56 &#xffe5;56.323 &#xffe5;56.32 &#xffe5;56.00 2.要使Word 能自动提醒英文单…

web安全渗透测试十大常规项(一):web渗透测试之JAVA反序列化

渗透测试之PHP反序列化 1. Java反序列化1.1 Java安全-反序列化-原生序列化类函数1.1.1 原生序列化类函数:1.2 Java安全-SpringBoot框架-泄漏&CVE1. Java反序列化 1、序列化与反序列化 序列化:将内存中的对象压缩成字节流 反序列化:将字节流转化成内存中的对象2、为什么…

Springboot整合MinIO实现系统文件的便捷式管理实例

一、MinIO简介 1.基础描述 MinIO 是一个高性能的对象存储系统&#xff0c;用于存储大量非结构化数据。它以简洁、高效、可靠和高扩展性著称&#xff0c;能够胜任各种数据密集型任务。MinIO 采用了与 Amazon S3 兼容的 API&#xff0c;使得用户无需额外学习即可上手使用。下面…

PriorityQueue详解(含动画演示)

目录 PriorityQueue详解1、PriorityQueue简介2、PriorityQueue继承体系3、PriorityQueue数据结构PriorityQueue类属性注释完全二叉树、大顶堆、小顶堆的概念☆PriorityQueue是如何利用数组存储小顶堆的&#xff1f;☆利用数组存储完全二叉树的好处&#xff1f; 4、PriorityQueu…

SpringBoot-通过注解@Vuale从全局配置文件中获取数据

除了通过注解ConfigurationProperties让JavaBean的所有属性和全局配置文件中配置项建立关联关系外&#xff0c;我们spring提供了一个Value注解&#xff0c;获取全局配置文件中的某个配置项的数据 接下来&#xff0c;我们重点说一下两个注解的的区别&#xff1a; Configuration…

汽车网络安全 -- 漏洞该如何管理

目录 1.漏洞获取途径汇总 2.CAVD的漏洞管理规则简析 2.1 通用术语简介 2.2 漏洞评分指标 2.3.1 场景参数 2.3.2 威胁参数 2.3.3 影响参数 2.3 漏洞等级判定 ​3.小结 在汽车网络安全的时代背景下&#xff0c;作为一直从事车控类ECU基础软件开发的软件dog&#xff0c;…

【html】用html写一个博物馆首页

效果图&#xff1a; 二级导航&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><l…

基于Java作业管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

八爪鱼现金流-029,网站裂变解决方案,10hongbao

现在完成renwu&#xff0c;可以得10hongbao &#xff01;&#xff01;&#xff01; 八爪鱼现金流 八爪鱼 背景&#xff1a; 个人开发者tuiguang 项目。一个用户推给两个用户&#xff0c;两个用户又分别推给两个用户&#xff0c;就实现了指数级增长。 业务场景分析&#xff1a;…

LeetCode 算法:翻转二叉树 c++

原题链接&#x1f517;&#xff1a;翻转二叉树 难度&#xff1a;简单⭐️ 题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 …

示例:WPF中推荐一个支持折叠展开的GridSpliter自定义控件GridSplitterBox

一、目的&#xff1a;推荐一个支持折叠展开的GridSpliter自定义控件GridSplitterBox 二、效果 实现功能&#xff1a;设置菜单显示位置&#xff0c;最小宽度&#xff0c;最大宽度&#xff0c;位置持久化保存 三、环境 VS2022 Net7 四、使用方式 1、安装nuget包&#xff1a;H…

Kafka~基础原理与架构了解

Kafka是什么 Kafka我们了解一直认为是一个消息队列&#xff0c;但是其设计初&#xff0c;是一个&#xff1a;分布式流式处理平台。流平台具有三个关键功能&#xff1a; 消息队列&#xff1a;发布和订阅消息流&#xff0c;这个功能类似于消息队列&#xff0c;这也是 Kafka 也被…

Windows Api如何创建一个快捷方式并且在开始菜单搜索到自己的应用

原文链接&#xff1a;http://cshelloworld.com/home/detail/1804473083243925504 当我们点击win10系统搜索框的时候&#xff0c;输入名称 &#xff0c;win10会帮助我们匹配到对应的应用。这里搜索框实际上就是windows系统的开始菜单。 接下来我们随便找一个应用&#xff0c;右…

如和完全免费快速访问外网?有亿点点不便利罢了

很鸡肋&#xff0c;但是可以试试 这个手机是真的可以使用谷歌的 不得不说有点意思&#xff0c;但肯定没啥用 地址跳转

光纤传感器十大品牌

十大光纤传感器品牌-光纤光栅传感器厂家哪家好-Maigoo品牌榜

java的单例集合迭代器

迭代器Iterator 根据之前的介绍我们知道&#xff0c;单例集合是由接口Collection定义的容器。Collection接口之下由定义了List接口和Set接口&#xff0c;其中List接口定义的容器的特征是有序可重复&#xff0c;而Set接口定义的容器的特征是无序不可重复的。 List接口定义的容器…