微软面试14题 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。

http://blog.csdn.net/v_JULY_v/article/details/6126406

题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。
如果有多对数字的和等于输入的数字,输出任意一对即可。
  例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
//由于数组已经过升序排列,所以,难度下降了不少。
//July、2010/10/19

#include <iostream.h>

bool FindTwoNumbersWithSum
(
int data[],           // 已经排序的 数组
unsigned int length,  // 数组长度   
int sum,              //用户输入的 sum
int& num1,            // 输出符合和等于sum的第一个数
int& num2             // 第二个数
)
{  
    bool found = false;
    if(length < 1)
        return found;
  
    int begin = 0;
    int end = length - 1;
  
    while(end > begin)
    {
        long curSum = data[begin] + data[end];
      
        if(curSum == sum)
        {
            num1 = data[begin];
            num2 = data[end];
            found = true;
            break;
        }
        else if(curSum > sum)
            end--;
        else
            begin++;
    }
    return found;
}

int main()
{
    int x,y;
    int a[6]={1,2,4,7,11,15};
    if(FindTwoNumbersWithSum(a,6,15,x,y) )
    {
        cout<<x<<endl<<y<<endl;
    }
    return 0;
}
4
11
Press any key to continue

扩展:如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,
如何在O(n)时间里找到这两个数字?

关于第14题,
1.题目假定是,只要找出俩个数,的和等于给定的数,
其实是,当给定一排数,
4,5,7,10,12
然后给定一个数,22。
就有俩种可能了。因为22=10+12=10+5+7。
而恰恰与第4题,有关联了。望大家继续思考下。:)。

2.第14题,还有一种思路,如下俩个数组:
1、 2、  4、7、11、15     //用15减一下为
14、13、11、8、4、 0      //如果下面出现了和上面一样的数,稍加判断,就能找出这俩个数来了。

第一个数组向右扫描,第二个数组向左扫描。

 

 

 

代码:

void FindTwoNumberWithSum(int data[],unsigned int length,
						  int sum,int &num1,int &num2)
{
	if(length<=1)
		return;
	int begin=0;
	int end=length-1;
	int cur=0;
	while(begin<end)
	{
		cur=data[begin]+data[end];
		if(cur==sum)
		{
			num1=data[begin];
			num2=data[end];

			return;
		}
		if(cur<sum)
		{
			begin++;
		}
		if(cur>sum)
			end--;
	}
}

void FindAnser(int data[],int cur,int sum,int idx,std::vector<int> col,int len)
{
	if(sum<=cur)
	{
		if(sum==cur)
		{
			std::vector<int>::iterator iter=col.begin();
			for(;iter!=col.end();iter++)
				cout<<*iter<<" ";
			cout<<endl;
		}
		return;
	}
	for(int i=idx;i<len;i++)
	{
		col.push_back(data[i]);
		FindAnser(data,cur+data[i],sum,i+1,col,len);
		col.pop_back();
	}
}

int main()
{
	int data[]={4,5,7,10,12};
	int num1,num2;
	//FindTwoNumberWithSum(data,sizeof(data)/sizeof(int),12,num1,num2);
	//cout<<num1<<" "<<num2<<endl;
	std::vector<int> col;
	FindAnser(data,0,22,0,col,sizeof(data)/sizeof(int));
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值