在升序数组中查找和等于给定值的两个数

【题  目】输入一个已经按升序排列的数组,一个给定的数字,在数组中查找两个数,使得它们的和等于给定的数字。要求时间复杂度为O(n),如果存在多对满足条件的数字对,只给出一对即可。例如:输入数组『1,2,4,7,11,15』,给定一个数字15,那么输出应该为『4,11』.

 

【思路1】我们先不考虑时间复杂度为O(n),按照最直观的思路来考虑,容易想到,我们一次固定数组中的一个数字,然后遍历这个数字之后的各个数字,判断和是否为给定的和,这样的时间复杂度为O(n2)。容易写出如下的代码:

复制代码
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 bool FindTwoNumbers(int array[],int length,int sum,int &num1,int &num2)
 6 {
 7     if(array == NULL || length < 2)
 8         return false;
 9 
10     for(int i = 0;i < length - 1;++i)
11     {
12         for(int j = i + 1;j < length;++j)
13         {
14             if(array[i] + array[j] == sum)
15             {
16                 num1 = array[i];
17                 num2 = array[j];
18                 return true;
19             }
20         }
21     }
22 
23     return false;
24 }
25 
26 int main()
27 {
28     cout<<"Enter the length of your array:"<<endl;
29     int arraylength = 0;
30     cin>>arraylength;
31     int *p = new int[arraylength];
32 
33     cout<<"Enter the numbers in your array:"<<endl;
34     for(int i = 0;i < arraylength;++i)
35     {
36         cin>>p[i];
37     }
38 
39     cout<<"Enter a sum you want to find:"<<endl;
40     int result = 0;
41     cin>>result;
42     
43     int a = 0;
44     int b = 0;
45     FindTwoNumbers(p,arraylength,result,a,b);
46 
47     cout<<"the two numbers are:"
48         <<"\t"<<a<<"\t"<<b<<endl;
49     
50     delete[] p;
51     return 0;
52 }
复制代码

运行结果如下:

 

【思路2】上面的算法时间复杂度为O(n2),但是这个算法有一个好处就是,对于不排序的数组也是能够适用的,因为我们采用的方法是遍历,对于排序不排序,我们并不关心。这也从一个侧面说明了上面的算法时间复杂度较高的原因是:我们并没有充分利用数组是按升序排列的这个条件。如果考虑这个条件,我们会怎么做?

  我们考虑一种特殊的情况,数组是严格的等差数列,那么给定一个和,如果能够找到一对整数满足题条件,那么根据等差数列的性质,较大的数想左移动一个数字,叫小的数向有移动一个数字,就又找到了另一对满足条件的数对。那么对于一般情况,我们能否这样考虑:首先判断第一个数字和最后一个数字的和,如果这个和大于给定的和,那么就让最后一个数字左移;反之,如果它们的和小于给定的和,就让第一个数字右移,这样是合乎逻辑的,然而这个算法容易使人产生一个疑问,会不会漏掉呢?这需要严格的数学证明,笔者暂时还不能给出证明,待日后补充,也希望数学很牛的同学不吝赐教。该思路代码如下:

复制代码
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 bool FindTwoNumbers(int array[],int length,int sum,int &num1,int &num2)
 5 {
 6     //无效输入,返回false
 7     if(array == NULL || length < 2)
 8         return false;
 9 
10     int *start = &array[0];
11     int *end = &array[length -1];
12 
13     while(start < end)
14     {
15         if((*start + *end) == sum)
16         {
17             num1 = *start;
18             num2 = *end;
19             return true;
20         }
21         
22         //小于给定和,较小的数右移
23         else if((*start + *end) < sum)
24         {
25             start++;
26         }
27         
28         //大于给定和,较大的数左移
29         else if((*start + *end) > sum)
30         {
31             end--;
32         }
33     }
34 
35     return false;
36 }
37 
38 
39 int main()
40 {
41     cout<<"Enter the length of your array:"<<endl;
42     int arraylength = 0;
43     cin>>arraylength;
44     int *p = new int[arraylength];
45 
46     cout<<"Enter the numbers in your array:"<<endl;
47     for(int i = 0;i < arraylength;++i)
48     {
49         cin>>p[i];
50     }
51 
52     cout<<"Enter a sum you want to find:"<<endl;
53     int result = 0;
54     cin>>result;
55     
56     int a = 0;
57     int b = 0;
58     FindTwoNumbers(p,arraylength,result,a,b);
59 
60     cout<<"the two numbers are:"
61         <<"\t"<<a<<"\t"<<b<<endl;
62     
63     delete[] p;
64     return 0;
65 }
复制代码

运行结果如下:

 

 


References:

程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/2541117420072143251809/

注:

1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。

2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。

相关推荐
<p> 欢迎参加英特尔® OpenVINO™工具套件初级课程 !本课程面向零基础学员,将从AI的基本概念开始,介绍人工智能与视觉应用的相关知识,并且帮助您快速理解英特尔® OpenVINO™工具套件的基本概念以及应用场景。整个课程包含了视频的处理,深度学习的相关知识,人工智能应用的推理加速,以及英特尔® OpenVINO™工具套件的Demo演示。通过本课程的学习,将帮助您快速上手计算机视觉的基本知识和英特尔® OpenVINO™ 工具套件的相关概念。 </p> <p> 为保证您顺利收听课程参与测试获取证书,还请您于<strong>电脑端</strong>进行课程收听学习! </p> <p> 为了便于您更好的学习本次课程,推荐您免费<strong>下载英特尔® OpenVINO™工具套件</strong>,下载地址:https://t.csdnimg.cn/yOf5 </p> <p> 收听课程并完成章节测试,可获得本课程<strong>专属定制证书</strong>,还可参与<strong>福利抽奖</strong>,活动详情:https://bss.csdn.net/m/topic/intel_openvino </p> <p> 8月1日-9月30日,学习完成【初级课程】的小伙伴,可以<span style="color:#FF0000;"><strong>免费学习【级课程】</strong></span>,级课程免费学习优惠券将在学完初级课程后的7个工作日内发送至您的账户,您可以在:<a href="https://i.csdn.net/#/wallet/coupon">https://i.csdn.net/#/wallet/coupon</a>查询优惠券情况,请大家报名初级课程后尽快学习哦~ </p> <p> <span style="font-size:12px;">请注意:点击报名即表示您确认您已年满18周岁,并且同意CSDN基于商务需求收集并使用您的个人信息,用于注册OpenVINO™工具套件及其课程。CSDN和英特尔会为您定制最新的科学技术和行业信息,将通过邮件或者短信的形式推送给您,您也可以随时取消订阅不再从CSDN或Intel接收此类信息。 查看更多详细信息请点击CSDN“<a href="https://passport.csdn.net/service">用户服务协议</a>”,英特尔“<a href="https://www.intel.cn/content/www/cn/zh/privacy/intel-privacy-notice.html?_ga=2.83783126.1562103805.1560759984-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">隐私声明</a>”和“<a href="https://www.intel.cn/content/www/cn/zh/legal/terms-of-use.html?_ga=2.84823001.1188745750.1560759986-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">使用条款</a>”。</span> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页