快速寻找满足条件的两个数

能否快速找出一个数组中的两个数,让这两个数之和等于一个给定的数字,为了简化起见,我们假设这个数组中肯定存在至少一组符合要求的解。

解题思路:

可以先将数组升序排序,然后设定变量i = 0,j = size - 1,看array[i] + array[j] 是否等于sum, 如果相等,则结束。如果小于sum,则 i = i + 1; 如果大于sum,则 j = j - 1。这样只需要在排好序的数组上遍历一次就可以得到最后的结果,时间复杂度为O(n), 加上排序的时间复杂度,总的复杂度为O(n*log2n)。

【代码】

#include <stdio.h>

void swap(int array[],int low,int high)
{
	int temp;
    temp=array[low];
	array[low]=array[high];
	array[high]=temp;

}


void quicksort(int array[],int low,int high)
{
	int i=low,j=high;
	int pivot;
	int pivotkey;
	pivotkey=array[low];
	if(low<high)
	{
		while(i<j)
		{
			while(i<j&&array[j]>=pivotkey)
				j--;
			swap(array,i,j);
			while(i<j&&array[i]<=pivotkey)
				i++;
			swap(array,i,j);

		}
		pivot=i;	
    	quicksort(array,low,pivot-1);
	    quicksort(array,pivot+1,high);
	}
}

int sum2(int array[],int size,int sum,int index1[],int index2[])
{
	int i=0;
	int j=size-1;
	int k=0;
	while(i<j)
	{
		if((array[i]+array[j])>sum)
			j--;
		else if((array[i]+array[j])<sum)
			i++;
		else
		{
			index1[k]=i;
			index2[k]=j;
			k++;
			i++;
			j--;
		}
	}
	return k;
}

void main()
{
	int a[6]={6,8,-3,0,2,4};
	int i;
	quicksort(a,0,5);
	for(i=0;i<6;i++)
		printf("%d ",a[i]);
	printf("\n");
	int index1[6];
	int index2[6];
	int result;
	result=sum2(a,6,10,index1,index2);
	printf("%d\n",result);
	for(i=0;i<result;i++)
        printf("%d %d\n",a[index1[i]],a[index2[i]]);
	printf("\n");
}

输出为[-3,0,2,4,6,8]

2 8

4 6

问题?如果[-3,0,2,2,8,8]

输出2 8

       2 8

即可能有重复的情况。

int sum2(int array[],int size,int sum,int index1[],int index2[])
{
	int i=0;
	int j=size-1;
	int k=0;
	while(i<j)
	{
		if((array[i]+array[j])>sum)
		{
			//注意,跳过重复的元素
			while(i<j&&array[j]==array[j-1])
			{
     			j--;
			}
			j--;
		}
		else 
		{
			if((array[i]+array[j])<sum)
			{
				//注意,跳过重复的元素
				while(i<j&&array[i]==array[i+1])
				{
					i++;
				}
				i++;
			}
			else
			{
				index1[k]=i;  
				index2[k]=j;
				k++;
				//注意,跳过重复的元素
				while(i<j&&array[j]==array[j-1])
				{
					j--;
				}
				while(i<j&&array[i]==array[i+1])
				{
					i++;
				}
				i++;
				j--;
			}
		}
	}
	return k;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值