No.1 两数之和
解题用时_Time
- 难度:简单
- 类型:数组
- 解题用时:1H
题目说明_Question
No.1题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
题目分析_Analyse
- 一个列表 nums=[] 列表中数据为整型 一个 target int类型
- target = nums 中的两个整数相加
- nums 中同一个元素只能用一次 、一个输入只有一个解
自己结题思路_MyAnswer
Summary:自己的两种方法用时均太长,测试用例数据庞大,证明我的解法效率较低
第一次写,a+b=c b=c-a!最基础的数学中的交换律都忘记使用!
# 1. 采用全部遍历(穷举)相加的方式 所有的元素都加一遍查看是否存在等于target对象
# 2. 可能存在空列表 首先判断
# 3. 由于 同一个元素不能使用两边 所以可以新建一个列表去掉已使用的元素
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# 1. 判空
if nums:
# 2. 遍历
for a in nums:
# 3. 复制一个新的列表
# 可变类型的复制 否则还是仍然使用之前的数据的引用
nums1 = copy.deepcopy(nums)
nums1.remove(a)
for b in nums1:
if a + b == target:
# 找出 b 在 nums中的位置
a_index = nums.index(a)
# 由于可能存在 多个数字一样的情况 找出后替换
nums[a_index] = '1'
b_index = nums.index(b)
# 返回 a 和 b_index
return list((a_index, b_index))
else:
continue
else:
return []
# ===========方法改进===========
# 第一次写,没有意识到这个问题,题目分析不够透彻~
# 由于 a + b = target 所以 b = target - a 少了一个for循环
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
if nums:
for a in nums:
# 可变类型的复制 否则还是仍然使用之前的数据的引用
nums1 = copy.deepcopy(nums)
nums1.remove(a)
b = target - a
if b in nums1:
# 找出 a/b 在 nums中的位置
a_index = nums.index(a)
# 由于可能存在 多个数字一样的情况 找出后替换
nums[a_index] = '1'
b_index = nums.index(b)
# 返回 a 和 b_index
return list((a_index, b_index))
else:
continue
else:
return []
测试用例真的太长了
大佬结题思路_AwesomeAnswer
解法一
Summary : 看了官网的解答,自己忽略一个问题,每次遍历的时候第1个数只需要跟第2个数以及之后的数相加即可(题目条件:每个数只能用一次),因为之前的数已经加过了!!!!!
这个也许也是在数据量庞大的情况下,我自己的写法用时过长的原因
# 其中 N 是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
# 时间复杂度:O(N²) 运行用时:5224ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
n = len(nums)
# 这里使用 nums的长度来控制外层遍历次数即可
for i in range(n):
for j in range(i + 1, n):
if nums[i] + nums[j] == target:
return [i, j]
# 而且这里没有进行对nums的直接判空,如果没有满足两个整数符合条件,直接返回空列表!
return []
解法二
Summary: a+b=c b=c-a! 添加交换律使用
# 在解法一的程度上优化 a + b = target 所以 b = target - a 少了一个for循环
# 时间复杂度O(n) 运行用时:883ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
n = len(nums)
# 这里不变
for a in range(n):
b = target - nums[a]
if b in nums:
c = nums.index(b)
if c == a:
continue
else:
return [a, c]
else:
continue
return []
解法三
Summary:enumerate() 和 dict()使用
# 使用哈希形式的字典存储值、下标然后进行取key判断 + (target - a = c)
# 时间复杂度O(n) 运行用时:60ms
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
temp_dict = {}
for key,value in enumerate(nums):
# 注意这里的 in 判断的是字典的key值,而不是value
if target - value in temp_dict:
return [temp_dict[target-value], key]
# 所以存储的时候用 数值作为字典的key 下标作为value值存储
return temp_dict['value'] = key
# 没有两个数满足条件直接返回空列表
return []
总结_Summary
1. 题目解读方面
- 题目中隐含的算式关系,列清楚,思考哪些是自己可以用到解题上的
- 然后如果是遍历的情况,是否可以尽量减少没有意义的遍历(枚举)?
2. 语法使用上
-
enumerate() 函数的使用,会把数值还有对应的下标同时遍历,并且,可以利用遍历出来的这两个数值辅助我们解题
-
dict() 字典类型的使用,字典在python中本身的时间复杂度就小,所以尽量使用它实现解题过程