LeetCode 第一题 (Python)

本文针对LeetCode上的经典题目“两数之和”,介绍了多种解题思路及算法优化过程。首先通过双重循环实现了暴力求解,然后进一步探讨了如何通过改进算法降低时间复杂度,最终采用字典数据结构实现了高效查找。
部署运行你感兴趣的模型镜像

题目内容

Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example: Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例: 给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

今天做了leetcode的第一道题,题意很简单,就是给定一组数和一个目标值,从这组数中找到两个数加起来等于目标值,输出目标值的下标。

刚刚见到这道题,没有多想(缺点),直接使用暴力遍历,两个循环嵌套,逐个进行相加运算,复杂度是O(n2)

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 target == nums[i] + nums[j]:
                    return [i, j]

这种方法提交之后超过了时间限制。所以必须改进算法。
原代码当中内部循环每一次循环都要计算一次求和,即

target == nums[i] + nums[j]

所以,可以考虑将这一步放入上一级循环,代码变为

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

这样就可以提交了,但是速度依然十分缓慢,要提高速度就要使用新的算法,查找大神的解法,找了一篇博客,[LeetCode]题解(python):001-Two-Sum
这篇博客提供了三种解法
第一种就是暴力解法,速度慢
第二种是将这组数先排序,再利用“夹逼定理”来处理,排序算法还未接触,所以暂时不考虑。
第三种是使用python中的dict,和C++中的map功能一样,建立一个字典,字典的关键字是这组数的值,字典的内容是这组数的值,我们查找target-nums(size)和nums(size)是否在字典中来找到答案。
博客中给出了第三种方法的代码,实现如下:

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d={}
        size=0
        while size < len(nums):
            if not nums[size] in d: 
                d[nums[size]] = size
            if target-nums[size] in d:
                if d[target-nums[size]] < size:
                    return [d[target-nums[size]],d[nums[size]]]
            size = size + 1

代码提交之后,显示了运行错误,错误的实例是

输入:[3,3]  6
输出:[0,0]
预期:[0,1]

dict中的关键字不能重复,当给定的数中有重复数字时,则会导致这一步

if not nums[size] in d: 
                d[nums[size]] = size

构建字典不成功,无法正确的进行计算。
所以,对上述代码进行改进。
因为出错的地方是构建字典这一步,我们每一次都把nums(size)写入字典,再进行target-nums(size)的寻找。
所以,可以想到,我们可以先进行target-nums(size)的寻找,如果找到直接输出,如果未找到,再写入字典,这样就避免了重复元素对构建字典的影响。
改进后的代码是

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d={}
        size=0
        while size < len(nums):
            if target-nums[size] in d:
                if d[target-nums[size]] < size:
                    return [d[target-nums[size]],size]
            else:
                d[nums[size]] = size
            size = size + 1

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值