LeetCode1. 两数之和

本文深入解析LeetCode经典题目“两数之和”的多种解题策略,包括直接双层遍历、作差查找、字典存储等方法,对比不同算法的时间与空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解决方法

方法一:直接两层遍历

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return[i,j]
        return 0 

Time Complexity: O ( n 2 ) O(n^2) O(n2)
时间太长,超出时间限制

方法二:作差,整个列表查找

思路:一层循环遍历整个列表nums每个值nums[i]
(1)target-nums[i]作差,
(2)判断如果差值在列表中,并且不是nums[i],则找到了这两个数值。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """        
        for i in range(len(nums)):
            dif = target - nums[i] #相减作差
            if(dif in nums and (nums.index(dif) !=i)): # 若差在列表中,且不是同一个值          
                return [i, nums.index(dif)]   #则找到了和为target的两个数
        return 0 

Time Complexity: O ( n ) O(n) O(n)
Auxiliary Space: O ( 1 ) O(1) O(1)

方法三:作差,从列表i+1开始查找

方法基本和前一个一样。只是考虑列表中存在相同元素,判断差值是否在nums[i+1:]中,
同时返回索引改为list[i + 1].index + i + 1

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
        len_nums = len(nums)
        for i in range(len_nums):
            dif = target - nums[i]         
            if dif in nums[i+1:]: 
                dif_index = nums[i + 1:].index(dif)+i+1
                return [i, dif_index]
        return 0

减少了查找长度,时间缩短了一点。
Time Complexity: O ( n ) O(n) O(n)
Auxiliary Space: O ( 1 ) O(1) O(1)
我们这里只用一次循环,但是循环中我们有查找操作(如果每次查找都是最差情况,那么我们要花O(n)的时间复杂度),并且查找索引的时候我们使用了index函数和切片操作,这些都是非常消耗时间的。

方法四:作差,从头到 i 查找

我们可以每次从nums[:i]中去查找是否有target - nums[i]。这种做法就避免了上述问题中的查找最差的情况

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
        len_nums = len(nums)
        for i in range(len_nums):
            dif = target - nums[i]         
            if dif in nums[:i]:  
                return [nums.index(dif), i]
        return 0

我们无法再优化index和切片操作,现在的问题就只存在在list这个结构上了,那么有没有更加适合这个问题的数据结构呢?

方法五:作差,字典存储查找

我们可以通过哈希表来存储nums[:i],在python里面的map内部实现就是通过哈希表。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        nums_hash = {}
        len_nums = len(nums)
        for i in range(len_nums):
            dif = target - nums[i]         
            if dif in nums_hash:  
                return [nums_hash[dif], i]
            nums_hash[nums[i]] = i
        return 0

执行时间短了很多,但是占用了空间。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值