day1_leetcode1

Leetcode第一题
1. 题目:
         


2. 我的第一思路是利用两次循环,将列表中的数两两相加,如果出现和为target,则返回。注意,由题目的意思,默认结果是只 有一对符合题意的,所以直接可以return的。所以下面是我的第一个解法:

class Solution:
    def twoSum(self, nums, target):
        for index in range(0, len(nums)):
            if nums[index+1]:    
                # 判断是否已经到最后一个元素。其实这一句可以不用,因为题意是默认有且只有一对的,所以不会超出列表范围的。
                for row in range(index+1, len(nums)):
                    if nums[index] + nums[row] == target:
                        return [index, row]


    这样是可以通过的,但是,我们来看一下复杂度。

    基本操作执行次数的函数 T(n) = n^2+n,时间复杂度就是O(n) = n^2。很明显,这样的结果肯定是很low的。呐,结果截图如下
         
    图中的第二列表示的是执行用时,第三列表示的是内存消耗,第四列是使用的语言。我记得好像是打败了0.xxx%的人吧(额。。。。)。


3. 影响复杂度主要因素是因为循环的次数,那这下重新组织一下思路,又想到第二种解法。就是只用一层循环,然后用target-         nums[index],如果该数在nums中,说明找到一对符合的,然后将索引输出即可。因此第二种解法如下:

class Solution:
    def twoSum(self, nums, target):
        for index in range(0, len(nums)):
            if target-nums[index] in nums and nums.index(target-nums[index]) != index:
                return [index, nums.index(target-nums[index])]

        现在看一下复杂度。首先T(n) = n,时间复杂度是O(n) = n,很明显比第一种方法要好很多。
        现在解释一下那个判断语句。target-nums[index] in nums这个就是要保证相减之后的结果能在nums中,表示nums中能找到一个数可以和当前循环的数相加之后等于target。

       但是这儿是不是有个问题呢?比如输入是nums=[3,3], target=6,那么结果就是[0,0],因为我使用python中自带的.index(value)方法,这样获取到的是这个列表中的第一个符合value。 所以还得再加一个条件,就是要获取到的这个value的索引不等于当前的索引。那还是刚刚举的那个例子,输出结果就会是[1, 0],不是[0, 1]的原因很明显,就是第一次循环的时候,target-nums[index]的值是3,而当前的数就是3,所以我们就跳到下一次循环了,然后第二次循环时,target-nums[index]的值是3,用.index(value)获取到的索引是0,所以符合条件,可以通过。
        但是问题又来了,那这样我们明明可以在第一次循环就得出的结果,要跑到第二次循环来,显然浪费了时间,所以怎么优化一下代码呢?现在可以这样想,既然我知道要和当前循环到的数相加等于target的数肯定在后面,那不就可以使得index(value)获取到的索引如果是当前的,那么就让它往后再找,如果找到了那就返回,这样不就可以少一点循环了。

       那么怎么改呢?
现在来看一下index()方法,这就是说,我们可以指定index从哪个索引开始查找,既然我们要找的数肯定在当前循环到的值得后面,那就可以修改代码如下(主要是修改了index(value, start)),另外,index()如果找不到话,会报错,所以要加一个异常处理。

class Solution:
    def twoSum(self, nums, target):
        for row in range(0, len(nums)):
            try:
                    if target-nums[row] in nums and nums.index(target-nums[row], row+1) != row:
                    return [row, nums.index(target-nums[row], row+1)]
            except:
                pass


    看一下执行结果:
      
       但是有点想不明白,我第一次执行时,内存消耗是7.9MB,第二次就随便改了一下缩进,和一些小格式之后,内存消耗变成了上面这样。。。。不过还是有点小满足的。


4. 到这儿就差不多了夜深了,去看一下同样用python3的人提交的更优秀的代码。别人的代码如下:
         
哈???36ms。这个代码的复杂度O(n) = n,但是人家的为什么就这么优秀?开挂了。这就是代码的魅力所在了。还睡什么觉。好好理解了这个代码之后,查一下enumerate()的使用。就是每次循环输出的是两个值,一个是索引,一个是列表中的索引对应的值。例如代码:
n_list = [1, 2, 3, 6]
for k, v in enumerate(n_list):
    print(k, v)
结果:
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大骨熬汤

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

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

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

打赏作者

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

抵扣说明:

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

余额充值