Leecode刷题笔记_Python版本_Array专题_Two Sum解法总结
题目概述
题目细节点梳理:
- return的结果是数组中的下标;
思路总结
这道题目比较巧妙的解法一般有以下几种常见的思路:
- 存储为有序的字典,利用二分法遍历数组查询结果
- 利用Hash表反向做映射
Python基础语法复习
在开始写代码之前,需要先复习几个Python的小技巧:
- enumerate函数的运用
enumerate(X,[start=0]);
#参数X可以是一个迭代器(iterator)或者是一个序列,也可以是一个字典。
#参数start是起始计数值,默认从0开始
```python
a = {1: 1, 2: 2, 3: 3}
for i , item in enumerate(a):
print (i, item)
Output:
0 1
1 2
2 3
b=[1,2,3,4,5,6]
for i,item in enumerate(b):
print (i, item)
Output:
0 1
1 2
2 3
3 4
4 5
5 6
下面是把start设置为10,输出结果下标将是从10开始,不再是默认的0.
b = [1,2,3,4,5,6]
for i,item in enumerate(b, start=10):
print(i,item)
Output:
10 1
11 2
12 3
13 4
14 5
15 6
- Get() 函数的应用
dict_name.get(key, default = None)
# key: 要设置默认值的Key
# default: 要返回key的值,可以是任何值,如整形、字符串、列表、字典等
# return: 如果字典中key本来有值,那么返回的是字典中Key所对应的值,如果没有,那么返回“default”中的值。
- 排序sorted(d.items(), key=lambda x: x[1])的使用
sorted(d.items(), key=lambda x: x[1])
#d.items() 为待排序的对象
#key=lambda x: x[1] 为对前面的对象中的第二维数据(即value)的值进行排序
#key=lambda 变量:变量[维数] 。维数可以按照自己的需要进行设置。
下文开始是几种主流的、有意思的解法
二分法
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
nums = enumerate(nums)
nums = sorted(nums, key = lambda x:x[1])
l,r = 0, len(nums)-1
while l<r:
if nums[l][1]+nums[r][1] == target:
return [nums[l][0],nums[r][0]]
elif nums[l][1]+nums[r][1] < target:
l += 1
else:
r -= 1
详细思路解释:
- 用enumerate函数生成一个字典
- 用sorted函数将字典进行排序,排序的依据是每个nums中的第二个元素
- 设两个指针 l 和 r ,分别指向第一个元素和最后一个元素
- 进入循环,如果 l 和 r 所指的元素和正好是我们target的数,我们就把 l 和 r 所指元素对应的序号返回
- 如果和小于target,就把左边的指针向右移,否则,把右边的指针向左移
做题时出现的错误:
if nums[l][1]+nums[r][1] = target:
哈希算法
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d = {}
for i,x in enumerate(nums):
if target-x in d:
return d[target-x],i
else:
d[x]=i
详细思路解释:
- 利用enumerate把原来的一个数组sums变成一个字典
- 遍历字典中的每一个元素,提取出 i 是序号,x 是序号对用的元素
- 接下来这一步用了很有趣的方法,核心思想是hash映射
把序号 i 存入到 d 的下标为 x 的地方,如果说 target-x 的值在d中,那说明就产生了一组解,输出即可
该方法的局限性:
- 解只有一个
哈希算法拓展(打破局限性)
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d= {}
for i,x in enumerate(nums):
d[x] = d.get(x,i)
res = []
for i,x in enumerate(nums):
y = target - x
if y in d and d[y] != i:
res += [i, d[y]]
return res
详细思路解释:
- 利用enumerate把原来的一个数组sums变成一个字典
- 遍历字典中的每一个元素,提取出 i 是序号,x 是序号对用的元素
- 提取出d中的元素 x,如果这个 x 不存在的话,就把 i 放在下标为 x 的地方,其实也是hash表的映射
- 设一个空的数组res用于存储结果
- 再次遍历字典中的每一个元素,对于每一个元素 x 来说,如果 y = target - x, y 值在 d 中,并且确认 y 不是 x 本身(很好的检验了不能重复使用同一个数字),我们就得到了一组解
- 把解添加到 res 序列中,继续找下一组解
做题时出现的错误:
for i,x in enumerate(nums):
y = target - x
if y in d and d[y] != i:
res += [i, d[y]]
return res
#return的锁进
当第一个数不满足条件的时候,就结束了,不能够继续检验之后的数
over.
2019.8.27 2:20