和为s的两个数字

来源:互联网 发布:win7的软件快捷方式 编辑:程序博客网 时间:2024/04/27 21:23
题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输入:
每个测试案例包括两行:
第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和。其中1 <= n <= 10^6,k为int
第二行包含n个整数,每个数组均为int类型。
输出:
对应每个测试案例,输出两个数,小的先输出。如果找不到,则输出“-1 -1”
样例输入:
6 151 2 4 7 11 15
样例输出:
4 11

最直观的就是暴力的方式,先在数组中固定一个位置,在依次判断数组中其余n-1个数字与这个数字的和是否符合题意。代码如下。复杂度为O(n^2).


//暴力迭代void solution_1(int arr[],int len,int s,int *num1,int *num2){if(arr == NULL || len <= 1){return;}int i,j;for(i = 0; i < len; i++){for(j=i+1;j < len; j++){if(arr[i]+arr[j] == s){*num1 = arr[i];*num2 = arr[j];return;}}}}void func(int arr[],int len,int index,int s,int *num1,int *num2){if(index == len-1){return;}for(int i = index + 1; i < len; i++){if(arr[i] + arr[index] == s){*num1 = arr[index];*num2 = arr[i];return;}}func(arr,len,index+1,s,num1,num2);}//暴力递归void solution_2(int arr[],int len,int s,int *num1,int *num2){if(arr == NULL || len <= 1){return;}int index = 0;func(arr,len,index,s,num1,num2);}

显然上面的解法是不可取的,因为并没有利用到数组升序的性质。其实我们可以定义两个指针,low和high,分别指向数组首尾,并把两个指针所指向的数字求和,若和小于s,low指针后移,若和大于s,high指针前移。
代码:
#include<stdio.h>#include<stdlib.h>bool FindNumber(int arr[],int len,int s,int *num1,int *num2){if(arr == NULL || len <= 1){return false;}int low = 0,high = len-1;while(low < high){if(arr[high] + arr[low] == s){*num1 = arr[low];*num2 = arr[high];return true;}else if(arr[low]+arr[high] < s){low++;}else{high--;}}return false;}int main(){int n,s;while(scanf("%d %d",&n,&s) != EOF){int *arr = (int*)malloc(sizeof(int)*n);if(!arr){exit(-1);}int i;for(i = 0; i < n; i++){scanf("%d",arr+i);}int num1,num2;if(FindNumber(arr,n,s,&num1,&num2)){printf("%d %d\n",num1,num2);}else{printf("-1 -1\n");}free(arr);}return 0;}




1 0
原创粉丝点击