一、题目描述:
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]
示例 2:
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]
限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
二、解题思路:
1. 暴力破解:时间复杂度:O(n^2)
两层for循环遍历,把两数之和的所有可能值计算出来,看是否有符合条件的值,把符合条件的返回。
2. 双指针:时间复杂度:O(n)
因为数组是按递增排序的,所以最小数在最左边,最大数在最右边。可先使用最小数与最大数进行组合,相当于是把数组的头尾两个下标设定为left,right两个指针,left = 0, right = len(nums) - 1;
判断nums[left],nums[right]这两个数的和与指定数target的关系:
- 情况一:如果nums[left] + nums[right] == target,则表示下标为left、right的两个数符合条件;
- 情况二:如果nums[left] + nums[right] < target,则表示两数之和小于target,此时需要把left的下标右移+1,两数之和才可能得到更大的数,让两数之和更接近target。
- 情况三:如果nums[left] + nums[right] > target,则表示两数之和大于target,此时需要把right的下标左移-1,两数之和才可能得到更小的数,让两数之和更接近target。
如果下标letf与下标right相遇时,还没有找到符合条件的两个数,则表示该数组中没有符合条件的两个值。
三、代码实现:
1.暴力破解(时间复杂度:O(n^2))
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)-1):
for j in range(i + 1, len(nums)):
if nums[i] + nums[j] == target:
return [nums[i], nums[j]]
return None
2.双指针(时间复杂度:O(n)):
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
left = 0
right = len(nums) -1
while left < right:
if nums[left] + nums[right] == target:
return [nums[left], nums[right]]
elif nums[left] + nums[right] < target:
left += 1
else:
right -= 1
return None
s = Solution()
print(s.twoSum([2,7,11,15], 9))
print(s.twoSum([2,3,7,11,15], 10))
print(s.twoSum([10,26,30,31,47,60], 40))