每天一道算法题(2018.11.25)

题目:
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数(找出一组即可)。

示例:
mums = [2,3,5,6,7]
target = 10
nums[1]+nums[4]=3+7=10
返回[1,4]

猛地一想,这不是很简单么,每次取两个数,加起来看看是不是等于target就好了。具体地来说,就是遍历数组中的每个数,让其与之后的数相加,看结果是否等于target。比如,取2, 分别与3,5,6,7相加;再取3,分别与5,6,7相加,依此类推,直到找到符合条件的两个数为止。

这是最简单直接的思路,一个遍历里又嵌套有另一个遍历,当i=0,内循环执行n次;当i=1,内循环执行n-1次;…当i=n-1,内循环执行1次;所以Sn=1+2+…n; Sn=n(1+n)/2=n^2/2+n/2; 再加上外循环的执行次数n, Tn=O(n^2/2+n/2;+n) ,根据只保留最高阶项的原则,时间复杂度Tn=O(n^2), 那有没有时间复杂度低点的算法呢?

有没有一种不嵌套遍历的方法呢,答案是肯定的。

我们可以把这个题目想成一个相亲会的例子。要在一群人当中,找出一对相互匹配的人儿来。根据上面所述的思路,我们先以第一个人为基点,然后依次安排让后面的人来和这个人相亲;如果都没有合适的,那我们就为第二个人依次安排相亲见面会,依此类推。这个程序是不是烦锁了点呢?

我们可以让第一个人说出自己的找对象标准,记在一个小本本上,然后去找第二个人,看第二个人的条件匹配不匹配第一个人的标准,同时,也把第二个人找对象标准也记在小本本上,再去找第三个人,看这个人的条件符不符合前面的人的条件,依次类推。也就是说,我们每次找人的时候都做了两件事,看这个人是不是符合前面人的标准,同时也把这个人的找对象标准也记了下来。这样一来,通过这个小本本,我们依次去问每一个人,最多一次就够啦。

回到算法本身,用python实现如下:
在这里插入图片描述

在这里,list就是这一群要找对象的人,target表示两个人匹配成功的条件,map就是我们的小本本啦。

map里记录了前面的人的择偶标准,如果当前找到的人和map里的要求匹配,那我们就算完成任务,成功匹配到两个人啦,如果没有,那就把当前这个人的择偶标准也记录到小本本上,再去见下一个人。

最后如果问完了所有人,都没有合适的两个人,那我们就只好return -1,-1, 表示没有在这群人里找到合适的两个人。

这个思路的复杂度是O(n),其实与上一个思路实质上不一样的地方呢,就在于我们每找到一个人,让这个人与前面的人做匹配的同时,也记下这个人的匹配标准。

总结一下,遍历的时候多存储些信息,也许就可以少些遍历的操作,也就是常说的用空间来换时间啦。

更多算法文章:
不含重复项的最长子串
左右括号问题
小偷问题
合并问题

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值