给定一个整数sum,从n个有序的元素的数组中寻找a,b,使得a+b的结果最接近sum,最快的时间复杂度?

之前遇到的一道算法题,这里记录一下。

算法思想:因为是有序的,所以我们用s存放第一个元素的下标,用e存放最后一个元素的下标,那么arr[s] 就是所有元素中最小的,arr[e]就是所有元素中最大的,所以我们判断arr[s] + arr[e] - sum的值是否大于0,如果大于0那就说明 arr[e] 太大了,那么就e--。如果小于0,arr[s] 太小了,那就s++。这个时候判断是否距离比上一个我们记录的距离更小,更小的话就更新,距离是|arr[s] + arr[e] - sum|这么算出来的。

因为没在oj或者LeetCode上找到,因此我也不确定代码有没有特殊值遗漏,不过大致思想是这样子的。程序能满足题目的要求

代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int arr[10000];
    int n,sum;
    scanf("%d %d",&n,&sum);
    for(int i=0;i<n;i++) {
        scanf("%d",&arr[i]);
    }
    int s=0,e=n-1;
    int dis = abs(arr[n-1] + arr[0] - sum);
    int result = dis;
    int resa,resb;
    int flag = 0;
    while(s<e){
        dis = arr[s] + arr[e] - sum;
        if(dis>0){
            if(abs(dis)<result) {
                result = abs(dis);
                resa = arr[s];
                resb = arr[e];
            }
            e--;
        }else if(dis<0){
            if(abs(dis)<result) {
                result = abs(dis);
                resa = arr[s];
                resb = arr[e];
            }
            s++;
        }else {
            printf("%d %d",arr[s],arr[e]);
            flag = 1;
            break;
        }
    }
    if(flag==0) {
        printf("%d %d",resa,resb);
    }

    return 0;
}

因为是从头和尾同时开始往中间走,他俩汇合即得到答案,故时间复杂度为O(n)。

posted @ 2020-09-17 16:31  小尾学长  阅读(1011)  评论(0编辑  收藏  举报