leetcode 两数之和各种算法解析

问题描述:
在这里插入图片描述

版本一:

首先最常见也是最不可取的通过暴力for循环求解,得到的结果自然时间复杂度和空间度都高

class Solution(object):
    def twoSum(self, nums, target):
        for i in range(len(nums)):
            for j in range(len(nums)):
                if(i==j):
                    print('a')
                elif(nums[i]+nums[j])==target:
                    break
            else:
                continue
            break
        return i,j
Solution()

版本二

版本二通过构建字典dict,将存在字典的键值对通过查表来找,时间复杂度为 O ( n ) \Omicron (n) On但这种情况下我们要考虑到一种很特殊的情况,因为字典通过键来找值是很方便的,反之不同,所以我们将索引设为值,数字设置为键是比较好的方法,但是因为字典是键唯一而值可以不唯一的,如果我们将数字设置为键就可能造成一种冲突,例如:
输入的 l i s t = [ 3 , 3 ] , t a r g e t = 6 list=[3,3],target=6 list=[3,3],target=6,如果按照以上的方法生成字典的话,就会造成字典只有一对键值对:
{ 3 : 0 } \left\{3:0\right\} {3:0}
而不是:
{ 3 : 0 , 3 : 1 } \left \{3:0 ,3:1 \right \} {3:0,3:1}
因此我们以相反的方式构建字典,但是这样从值去取得键不方便,而且会造成字典的重复利用,和题目中每个元素利用一次不符合,因此我们转到版本三,也是官方给出的版本.

class Solution(object):
    def twoSum(self, nums, target):
        dict_={}
        for i,num in enumerate(nums):
            dict_[i]=num
        for index,nums_ in enumerate(nums):
            s=dict_.copy()
            del s[index]
            other_nums=target-nums_
            if other_nums in s.values():
                return [index,list(s.keys())[list(s.values()).index(other_nums)]]

在这里插入图片描述

版本三

版本三在版本二的基础上,哈希求法,解决了键重复和重复利用同一个元素的问题,不仅效率更好而且更节约时间,如何做到的呢?关键在于这个代码:

            if another_num in hashmap:
                return [hashmap[another_num], index]
            hashmap[num] = index

我们版本二构建是将整个字典构建出来,再去寻找,而此版本一边赋值一边寻找,刚开始我认为这并不可能,但仔细思考才发现这种思路的精妙之处.首先举例我们找的两个值是A和B:
A + B = t a r g e t A+B= target A+B=target
两个数字是相互,例如我找到A,注意此时字典中没有B,然后我们迭代到B的时候,再通过字典找到A,这解决了什么问题了?我们版本二提出的键重复的问题,如果 A = 3 , B = 3 A=3,B=3 A=3,B=3就会产生版本所说的键重复,但如果按照版本三边赋值边迭代,当找到B的时候,我们就不会面对这个问题,因为B的索引是迭代过程中通过enumerate,而A的索引是通过找字典的键值对。
同样版本三可以让过程在一个for循环下,边赋值边寻找,节省时间和内存。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashmap = {}
        for index, num in enumerate(nums):
            another_num = target - num
            if another_num in hashmap:
                return [hashmap[another_num], index]
            hashmap[num] = index
        return None

在这里插入图片描述
总而言之
第一个是字典的应用是的时间复杂度降低
第二个是边赋值边索引解决了键值冲突的问题
第三个字典的值比键好找,所以最好将索引用作值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值