zoukankan      html  css  js  c++  java
  • 给定一个整数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)。

  • 相关阅读:
    集群任务管理系统SGE的简明教程
    三代全长转录组测序和组装
    quota
    基因组转座元件
    单倍体
    什么是寒武纪、志留纪、泥盆纪、白垩纪
    对组装之后的三代基因组进行polish
    使用 PhyML 构建进化树
    PAML软件中的mcmctree命令估算物种分歧时间
    OrthoMCL及orthofinder 两种软件进行聚类分析
  • 原文地址:https://www.cnblogs.com/xwxz/p/13685936.html
Copyright © 2011-2022 走看看