42、剑指offer--和为S的两个数字

题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 
输出描述:
对应每个测试案例,输出两个数,小的先输出。
 
解题思路:本题主要是如何保证找到的两个数的乘积是最小的。通过证明,定义start、end一个指向数组头,一个指向数组尾。如果相等,则为找到,大于sum,则end--,小于sum则start++,这样找到的第一组即为乘积最小的一组。
 1 class Solution {
 2 public:
 3     //此题关键如何找到乘积最小
 4     //找到的第一组(相差最大的)就是乘积最小的。
 5     //可以这样证明:考虑x+y=C(C是常数),x*y的大小。
 6     //不妨设y>=x,y-x=d>=0,即y=x+d, 2x+d=C, x=(C-d)/2, 
 7     //x*y=x(x+d)=(C-d)(C+d)/4=(C^2-d^2)/4,
 8     //也就是x*y是一个关于变量d的二次函数,对称轴是y轴,开口向下。d是>=0的,d越大, x*y也就越小。
 9     vector<int> FindNumbersWithSum(vector<int> array,int sum) {
10         vector<int> result;
11         if(array.empty())
12             return result;
13         int length = array.size();
14         int start = 0;
15         int end = length-1;
16         while(start < end)
17         {
18             int tmp = array[start] + array[end];
19             if(tmp == sum)
20             {
21                 //小的先输出
22                 result.push_back(array[start]);
23                 result.push_back(array[end]);
24                 break;
25             }
26             else if(tmp > sum)
27             {
28                 end--;
29             }
30             else
31             {
32                 start++;
33             }
34         }
35         return result;
36     }
37 };


 

posted @ 2017-06-15 16:20  qqky  阅读(158)  评论(0编辑  收藏  举报