LeetCode1. 两数之和、LeetCode2. 两数相加

两数之和

1. 暴力解法

思路:通过双重循环遍历数组中所有可能的两个元素组合,检查其和是否等于目标值,若找到则返回对应索引。

代码实现:

class Solution(object):
    def twoSum(self, nums, target):
        """
        暴力解法 - 时间复杂度 O(),空间复杂度 O(1)
        作为对比,提供暴力解法实现
        """
        # 双重循环遍历所有可能的组合
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                # 检查两个数的和是否等于目标值
                if nums[i] + nums[j] == target:
                    return [i, j]

        # 如果没有找到符合条件的两个数
        return []

复杂度分析:

时间复杂度:O (n²),需双重循环遍历数组,n 为数组长度。
空间复杂度:O (1),无需额外存储空间。

2. 哈希表解法

思路:利用哈希表(Python 字典)存储已遍历元素的值和索引,遍历过程中计算当前元素与目标值的 “补数”(target - 当前元素),若补数已在哈希表中,则直接返回补数索引和当前元素索引,实现一次遍历完成查找。

代码实现:

class Solution(object):
    def twoSum(self, nums, target):
        # 哈希表解法 - 时间复杂度 O(n),空间复杂度 O(n)
        # 使用字典存储已经遍历过的元素及其索引
        # 键为元素值,值为元素索引

        # 创建一个空字典用于存储已遍历的元素
        num_dict = {}

        # 遍历数组中的每个元素
        for i, num in enumerate(nums):
            # 计算需要的补数(target - 当前元素)
            complement = target - num

            # 检查补数是否已经在字典中
            if complement in num_dict:
                # 如果找到补数,返回补数的索引和当前元素的索引
                return [num_dict[complement], i]

            # 如果没有找到补数,将当前元素及其索引存入字典
            num_dict[num] = i

        # 如果没有找到符合条件的两个数(根据题目描述,这种情况不会发生)
        return []在这里插入代码片

复杂度分析:

时间复杂度:O (n),仅需一次遍历数组,哈希表查找操作平均时间复杂度为 O (1)。
空间复杂度:O (n),最坏情况下需存储数组中所有元素(哈希表最多存储 n 个键值对)。

3. 哈希表解法的工作流程(示例)

以 nums = [2, 7, 11, 15],target = 9 为例:
第一轮迭代(i=0,num=2):
补数 = 9 - 2 = 7
7 不在空字典中,将 {2: 0} 存入字典。
第二轮迭代(i=1,num=7):
补数 = 9 - 7 = 2
2 在字典中(索引 0),返回 [0, 1]。

4. 为什么哈希表更快?

查找效率:哈希表的查找操作平均时间复杂度为 O (1),而数组遍历查找为 O (n)。
一次遍历:无需双重循环,仅需遍历数组一次即可完成查找。
即时判断:每遍历一个元素就可立即判断是否存在匹配的补数,无需等待后续元素。

5. 哈希函数的作用(Python 字典中)

将键(元素值)转换为哈希值,用于快速定位存储位置。
通过哈希值直接访问对应值(索引),实现 O (1) 级别的数据存取效率。

6. 两种解法的复杂度对比

解法 时间复杂度 空间复杂度 适用场景
暴力解法 O(n²) O(1) 数组规模极小(n 很小)
哈希表解法 O(n) O(n) 数组规模较大(需优化效率)

两数相加

算法思路

该解决方案通过同时遍历两个链表,逐位相加并处理进位来解决问题。时间复杂度为O(max(m, n)),空间复杂度为O(max(m, n))。

你可以直接运行Python文件查看测试结果,或者在浏览器中打开HTML文件体验交互式可视化。HTML页面已经打开,你可以在上面尝试不同的输入并查看算法的执行过程。

代码实现

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        # 初始化结果链表的头节点和当前节点
        dummy_head = ListNode(0)
        current = dummy_head
        carry = 0  # 进位值

        # 遍历两个链表,直到都为空
        while l1 or l2:
            # 获取当前节点的值,如果链表为空则为0
            x = l1.val if l1 else 0
            y = l2.val if l2 else 0

            # 计算当前位的和以及进位
            sum_val = x + y + carry
            carry = sum_val // 10
            current.next = ListNode(sum_val % 10)
            
            # 移动到下一个节点
            current = current.next
            if l1:
                l1 = l1.next
            if l2:
                l2 = l2.next

        # 如果最后还有进位,需要添加新节点
        if carry > 0:
            current.next = ListNode(carry)

        # 返回结果链表的头节点(跳过虚拟头节点)
        return dummy_head.next

示例执行流程

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lcreek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值