题目:
给定一个升序排列的整数数组 numbers,从数组中找出两个数满足相加之和等于目标函数 target。
假设每个输入只对应唯一的答案,而且不可以重复使用相同的元素,返回两数的下标值,以数组性质进行返回
示例:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
可以使用我们之前博客中对于无序数组查找的方法进行查找。也可以使用二分法进行查找。所以这里我们不使用暴力算法和哈希表的方式解决这个问题。我们这里使用二分查找和双指针进行解题。
方法1:二分法
当我们遇到有序数组,并且是寻找元素的任务时,我们首先可以想到的是二分法查找,但是这里查找的是两个元素,那么怎么使用二分查找去寻找两个元素呢?
我们可以将其中的一个元素进行固定,然后再其他元素中去寻找剩下的一个元素就行了。接下来我们来看具体的代码。
# 二分法
def fun1(nums, target):
l = len(nums)
for i, x in enumerate(nums):
num1 = x # 固定其中一个数
num2 = target - num1 # 那么另一个数就是target-x
start = i+1 # 定义二分法的开头
end = l-1 # 定义二分法的结尾
while start <= end: # 二分法结束条件
mid = int(start + (end-start)/2 ) # [start, end]的中间值
num3 = nums[mid] # 查找中间值
if num2 == num3: # 如果查找值与num2相等就说明找到了
return [i, mid]
elif num3 > num2: # 如果查找值大于num2相等就说明num2可能在区间左边,所以修改边界end
end = mid-1
else: # 如果查找值小于num2相等就说明num2可能在区间右边,所以修改边界start
start = mid + 1
方法2:双指针法
这里使用的双指针不是前面学习的快慢指针。这里两个指针分别在数组的两端,我们判断两端值之间的和,根据和(sum)和目标值(target)之间的差距进行移动指针,每一次移动一下指针,逐渐缩小范围,直到找到唯一解。其具体算法如下:
# 双指针法
def fun2(nums, target):
l = len(nums)
left = 0
right = l-1
while left < right: # 如果两个指针重合就说明此题无解
sum = nums[left] + nums[right] # 将两个指针处的值相加
if sum == target: # 相等就输出下标
return [left, right]
elif sum < target: # 说明两个数小了要增加,所以左指针向右移
left += 1
else: # 说明两个数大了要减小,所以右指针向左移
right += 1
网友评论