给定一个数和一个数组,在数组中找到两个值之和为给定数,显示所有情况,要求复杂度为O(n);

请给出代码和解释... 请给出代码和解释 展开
 我来答
风若远去何人留
2018-01-25 · 知道合伙人互联网行家
风若远去何人留
知道合伙人互联网行家
采纳数:20412 获赞数:450108
专业C/C++软件开发

向TA提问 私信TA
展开全部

首先对数组进行排序,时间复杂度为(N*log2N)。

然后令i = 0,j = n-1,看arr[i] + arr[j] 是否等于Sum,如果是,则结束。如果小于Sum,则i = i + 1;如果大于Sum,则 j = j – 1。这样只需要在排好序的数组上遍历一次,就可以得到最后的结果,时间复杂度为O(N)。两步加起来总的时间复杂度O(N*log2N),下面这个程序就利用了这个思想,代码如下所示:

int getSumNum(int[] arr,int Sum),   //arr为数组,Sum为和   
{  
    int i,j;  
    for(i = 0, j = n-1; i < j ; )  
    {  
        if(arr[i] + arr[j] == Sum)  
            return ( i , j );  
        else if(arr[i] + arr[j] < Sum)  
            i++;  
        else  
            j--;  
    }  
    return ( -1 , -1 );  
}

它的时间复杂度是O(N)。

刚开始一直无法理解这样一定可以找到这个和吗?难道不会漏掉了解的位置。可以这么理解,假如排好序后的数组为1,3,6,a,9,12,17,28,b,35,46  ,那么i最初指向1的位置,j最初指向46的位置,比如所求的是Sum=a+b,a<b,a和b在数组中的某位置上。那么i和j在变化过程中,只考虑i遇到了a或者j遇到了b的时候,必定有一个先遇到,比如i遇到了a,那么这个时候j必定还没指到b,故这时j指到的值比b大,从而j减小直到b位置。同理若j先指到了b位置,那么i必定还没指到a(这是我们的前提),然后i现在指到的值比a小,故i增加,直到a位置。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式