寻找指定和的整数对
描述
给出若干个整数,询问其中是否有一对数的和等于给定的数。
输入
共三行:
第一行是整数n(0 < n <= 100,000),表示有n个整数。
第二行是n个整数。整数的范围是在0到10^8之间。
第三行是一个整数m(0 <= m <= 2^30),表示需要得到的和。
输出
若存在和为m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No。
样例
4
2 5 1 4
6
1 5
难度
中等,查找
解题思路
解法
采用二分查找,首先对数组从小到大排序,复杂度O(nlogn),从头到尾处理数组中的每个元素l[i],在大于l[i]的数中二分查找是否存在一个等于 expectsum - l[i]的数,复杂度也是O(nlogn)。两部分相加,总复杂度仍然是O(nlogn)。
采用尺取法,首先对数组从小到大排序;然后,设置两个变量i和j,分别指向头和尾,i初值是0,j初值是n-1,然后让i和j逐渐向中间移动,检查l[i]+l[j],如果大于预期值,就让j减1,如果小于预期值,就让i加1,直至l[i]+l[j] = expectsum。排序复杂度O(nlogn),检查的复杂度O(n),合起来总复杂度O(nlogn)。
代码
二分法
def search():
n = (int)(input())
l = []
a = input()
b = a.split(" ")
expectsum = (int)(input())
for i in range(n):
l.append((int)(b[i]))
l.sort()
i = 0
while(True):
left = i+1
right = n-1
while(left<=right):
mid = left + int((right-left) / 2)
if(l[i]+l[mid]>expectsum):
right = mid - 1
elif(l[i]+l[mid]<expectsum):
left = mid + 1
else:
print(l[i],l[mid])
return
i = i+1
search()
尺取法
def search():
n = (int)(input())
l = []
a = input()
b = a.split(" ")
expectsum = (int)(input())
for i in range(n):
l.append((int)(b[i]))
l.sort()
i = 0
j = n-1
while(i<j):
sum = l[i]+l[j]
if(sum>expectsum):
j = j-1
if(sum<expectsum):
i = i+1
if(sum == expectsum):
print(l[i],l[j])
return
search()