算法三个数之和

6 篇文章 0 订阅

快速找出一个数组中的三个数,让这三个数之和等于一个给定的值(编程之美)  

2012-08-16 14:25:18|  分类: 编程之美|字号 订阅

解法:时间复杂度为O(n^2)。如果数组已排序,利用解法1的双指针遍历法,可以在O(n)的时间内找到两个数之和等于一个給定的数。我们假设找到的三个数ai,aj,ak有ai<=aj<=ak,要让ai+aj+ak=sum,也就是要ai+aj=sum-ak,设subsum=sum-ak,很容易发现subsum的值只有n个,而确定ai+aj=subsum中的ai,aj只需要O(n)的时间,所以总的时间复杂度为O(nlogn+n*n)=O(n^2)
#include<iostream>
using namespace std;
void swap(int &x,int &y)
{
int temp=x;
    x=y;
    y=temp;
}
void QuickSort(int data[],int start,int end)
{
 int i=start;
 int j=end;
 int temp=data[start];
 if(start<end)
 {
   while(i!=j)
  {
     while(j>i&&data[j]>temp)
     {
           j--;
     }
    if(j>i)
    {
    swap(data[i],data[j]);
         i++;
     }
     while(j>i&&data[i]<temp)
    {
           i++;
    }
    if(j>i)
    {
        swap(data[i],data[j]);
         j--;
    }
    } 
     data[i]=temp;
    QuickSort(data,start,i-1);
    QuickSort(data,i+1,end);
  }

bool sum(int*data,int length,int sum,int&v1,int &v2,int &v3)
{
 bool found=false;
 if(data==NULL||length<=0)
  return found;
int ahead=0;
int behind=length-1;
for(int k=0;k<length;k++)
{
 if(k==ahead)  ahead++;
 if(k==behind) behind--;//允许每个数被选取多次
 int subSum=sum-data[k];
  while(ahead<behind)
 {
  int curSum=data[ahead]+data[behind];
  if(subSum==curSum)
  {
   v1=data[ahead];
   v2=data[behind];
   v3=data[k];
   found=true;
   break;
  }
  else if(subSum>curSum)
  {
   ahead++;
  }
  else 
  {
    behind--;
  }
   if(k==ahead)  ahead++;
   if(k==behind) behind--;//允许每个数被选取多次
 }
}
return found;
}
void main()
{   int v1;
    int v2; 
int v3;
 int data[]={1,12,3,131};
 QuickSort(data,0,3);
 if(sum(data,4,135,v1,v2,v3))
  {
    cout<<v1<<endl;
    cout<<v2<<endl;
cout<<v3<<endl;
  }
 for(int i=0;i<=3;i++)
 {
  cout<<data[i]<<endl;
 }


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值