1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
暴力求解
遍历每个元素n,都向后查找是否有等于target-n的元素的存在,有则直接返回索引。
- 时间复杂度:$O(n^2)$,对于每个元素,都需要遍历后面的元素,花费时间O(n)。一共含有n个元素,所以时间复杂度是$O(n^2)$。
- 空间复杂度:O(1)
1
2
3
4
5
6
7
8
9
10
11class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[j]==target-nums[i]:
return [i,j]
One-pass Hash Table
用哈希表(字典)保存数字n和索引的映射。
遍历查找数字n与目标数target的“互补数”时只需查找dic[target-n]是否存在即可。
- 时间复杂度:O(n),仅需要遍历list中的n个元素。每次只需要在字典中查找花费时间O(1)
- 空间复杂度:O(n),额外的空间依赖于哈希表中保存的与元素个数
1 | class Solution(object): |
167. 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
One-pass Hash Table
1 | class Solution(object): |
双指针
数组是升序数组,随后用两个变量指向数组的开头和结尾:分别指向nums[0]和nums[numsSize]。
- 如果nums[low]+nums[high] < target,则说明low指向的数太小,需要往后移动;
- 如果nums[low]+nums[high] > target,则说明high指向的数太大,需要前移
- 当两者相等,遍历结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
left,right=0,len(numbers)-1
while left<right:
sum=numbers[left]+numbers[right]
if sum<target:
left+=1
elif sum>target:
right-=1
else:
return [left+1,right+1]
15. 三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
基于2Sum & 哈希表
1 | class Solution(object): |
基于2Sum & 双指针
1 | class Solution(object): |
16. 最接近的三数之和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
双指针
1 | class Solution(object): |
18. 四数之和
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
1 | class Solution(object): |