两数之和
这是暴力法中第一次错误的案例
// 两数之和
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range (len(nums)):
for j in range (len(nums)):
if target == nums[i] + nums[j]:
return [i,j]
j=j+1
i=i+1
测试用例
输入[3,2,4] 6
输出[0,0]
预期输出[1,2]
出错原因在于没有考虑相同元素相加为目标数值的情况
且对于for循环理解不够
for index in range(length)
其中index是从0开始循环遍历数组的所有元素,
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range (len(nums)):
j=i+1
for j in range (len(nums)):
if target == nums[i] + nums[j]:
return [i,j]
j=j+1
如果如上述设置j=i+1作为index,其实它在第二层循环仍是从j=0开始的,所以如果我们想要应用j=i+1开始应该怎么写呢?如下
方法1 用时7444ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> 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]
j=j+1
i=i+1
用for j in range(i+1,len(nums))来表示从i+1到 len(nums)迭代,注意是区间是左闭右开的
其次这里记一下循环中使用else语句的用法:
在 python 中,for … else 表示这样的意思,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。
for num in range(10,20): # 迭代 10 到 20 之间的数字
for i in range(2,num): # 根据因子迭代
if num%i == 0: # 确定第一个因子
j=num/i # 计算第二个因子
print '%d 等于 %d * %d' % (num,i,j)
break # 跳出当前循环
else: # 循环的 else 部分
print num, '是一个质数'
输出结果:
10 等于 2 * 5
11 是一个质数
12 等于 2 * 6
13 是一个质数
14 等于 2 * 7
15 等于 3 * 5
16 等于 2 * 8
17 是一个质数
18 等于 2 * 9
19 是一个质数
这是利用list相关函数求解
思路是:list.count确保target-num1=num2的存在,其次用list.index函数找出其下标
方法2 用时968ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
numslen = len(nums)
j = -1
for i in range(numslen):
if (target - nums[i]) in nums: # 确保num2在数组中
if (nums.count(target - nums[i])==1) &(target-nums[i] == nums[i]): # 当数组中num2只存在一个,且num1=num2时,则找到的这个就是num1本身
continue
else:
j=nums.index(target-nums[i],i+1) # 找到num2的下标
break
if j>0:
return [i,j]
else:
return []
方法3 用时412ms
第二种是优化了num2的查找方法
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
lens=len(nums)
j=-1
for i in range(lens):
temp = nums[:i]
if (target-nums[i]) in temp:
j = temp.index(target-nums[i])
break
if j>=0:
return [j,i] #注意这里的返回值是反的
return []
通过python中diction字典来模拟哈希表查找
方法4 用时44ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap={}
for index,numx in enumerate(nums):
hashmap[numx]=index # 注意这里把key和value值反着装是因为下边get函数的应用
for i,num in enumerate(nums):
j = hashmap.get(target-num) # python中get函数是 dict.get(键)=值
if j is not None and i!=j: # j即要有定义,又不能是i本身,这样才能避免两个数重复使用
return [i,j]
这里注意 :
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
Python 2.3. 以上版本可用,2.6 添加 start 参数。
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three
但是要注意我们方法中的hashmap的应用是反着的,为了下表中get取出
还有一个关键点是 if的条件容易写错,
这种方法是不需要搜索整个字典,只搜索i前的字典即可
方法5 用时56ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap={}
for i,num in enumerate(nums):
if hashmap.get(target - num) is not None:
return [hashmap.get(target - num),i]
hashmap[num] = i #这句不能放在if语句之前,解决list中有重复值或target-num=num的情况
此外 说个题外话
实测三种判断方法运行100万次用时(win10 python3.7.3):
key in dict 用时 1.088 秒
dict.get(key) 用时 1.294 秒
dict[key] 用时 1.01 秒