算法实践:寻找指定和的整数对(二分查找,尺取法)

寻找指定和的整数对

描述

给出若干个整数,询问其中是否有一对数的和等于给定的数。

输入

共三行:

第一行是整数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()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值