在升序数组中选取2个数,使其和等于一个输入数字n

来源:互联网 发布:学编程需要英语吗 编辑:程序博客网 时间:2024/05/16 08:37

题目描述

这是一道某互联网公司的面试题,输入为一个以按升序排序好的数组和一个数字n,要求在数组中查找两个数,使得他们的和正好等于那个输入数字n。如果有多对数字的和等于n,输出任意一对即可。

朴素解法

使用两个变量i和j,利用两层循环遍历数组,当遇到data[i]+data[j]等于输入数字,并且i不等于j的时候,输出data[i]和data[j],即找到了所求的两个数字。下面是这种解法的代码:
void find1(int *data,int num){assert(NULL!=data);int i=0;int j=0;for(i=0;i<len;i++)for(j=0;j<len;j++){if((i!=j)&&((data[i]+data[j])==num)){printf(" %d + %d = %d  \n",data[i],data[j],num);return;}}printf(" not find them  \n");return;}

很容易看出,这种解法的时间复杂度是o(n^2),并且没有充分利用升序数组这一条件。

更加合理的解法

我们可以用两个变量找到数组的第一个元素和最后一个元素,即数组最小值和最大值。当这两个数字的和等于输入数字n,则输出结果即可。若两个数字的和小于n,则向右移动指向较小值的变量;若两个数字的和大于n,则向左移动指向较大值的变量。判断结束的条件是两个变量重合。

下面是这种解法的代码:
void find2(int *data,int num){assert(NULL!=data);int i=0;int j=len-1;while(i<j){if((data[i]+data[j])==num){printf(" %d + %d = %d  \n",data[i],data[j],num);return;}else if((data[i]+data[j])< num){i++;}else{j--;}}printf(" not find them  \n");return;}

小结

很显然,第二种解法的时间复杂度是o(n),要优于第一种的解法,并且能够充分利用题目中升序数组的条件。
原创粉丝点击