剖析3-sum问题(Three sum)

日常生活中经常遇到求解数组中是否存在和为0的三个数,即3-sum问题,为此本文介绍一些比较实用的方法,并在暴力计算的基础上对算法逐步改进,以达到最优的算法。

首先介绍一下2-sum问题,3-sum问题其实就是2-sum问题的一个扩展而已。对于2-sum问题,最一般的想法就是使用两层循环直接枚举数组中的所有元素对,直到找到和为0的元素对为止。

int sum_2()
{
	int res = 0;
	int n = data.size();
	for(int i=0; i<n; i++)
	{
		for(int j=i+1; j<n; j++)
		{
			if(data[i] + data[j] == 0)
			{
				res ++;
			}
		}
	}
	return res;
}

上述算法的由于包含了两层循环,因此时间复杂度为O(N^2)。

观察发现,上述算法时间主要花费在数据比对,为此可以考虑使用二分查找来减少数据比对时间,要想使用二分查找,首先应该对数据进行排序,在此使用归并排序对数组进行升序排列。排序所花时间为O(NlogN),排序之后数据查找只需要O(logN)的时间,但是总共需要查找N此,为此改进后算法的时间复杂度为O(NlogN)。

int cal_sum_2()
{
	int res = 0;
	for(int i=0; i<data.size(); i++)
	{
		int j = binary_search(-data[i]);
		if(j > i)	
		res++;
	}
	return res;
}
观察上述算法发现,我们在比对的过程中还是存在了一些冗余。因为排列后的数据是从最小的数开始匹配的,我们只需计算其与最后的数据的和是否为0即可,如果大于0,则说明不存在与最小数匹配的数,此时将用较小的数来替代最大的数,反之则选用较大的数替代最小的数,如此反复,只需要扫
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
代码#绘制图形分析满减优惠和形式和折扣率优惠形式 import matplotlib . pyplot as plt import re indexOne = data1['discount_rate']. astype (str). apply ( lambda x : re . findall ( '\d +:\ d +', x )!=[])#满减优惠形式的索引 indexTwo =data1('discount_rate'). astype ( str ). apply ( lambda x : re . findall ( '\d +\.\ d +', x )!=[])#折扣率优惠形式的索引 dfOne =data1.loc[indexOne,:]#取出满减优惠形式的数据 dTwo =data1.loc[indexTwo ,:]#取出折扣率优惠形式的数据 #在满减优惠形式的数据中,15天内优惠券被使用的数目 numberOne = sum (( dfOne ('date')- dfOne[ 'date_received ']). dt . days <=15) #在满减优惠形式的数据中,15天内优惠券未被使用的数目 numberTwo = len ( dfOne )- numberOne #在折扣率优惠形式的数据中,15天内优惠券被使用的数目 numberThree = sum (( dfTwo['date']- dfTwo[' date_received ']. dt . days <=15) #在折扣率优惠形式的数据中,15天内优惠券未被使用的数目 numberFour = len( dfTwo )- numberThree #绘制图形 plt . figure ( figsize =(6,3)) plt . rcParams ['font . sans-serif']=' Simhei ' plt . subplot (1,2,1) plt . pie (( numberOne , numberTwo ), autopct ='%.1f%%', pctdistance =1.4) plt . legend (['优惠券15天内被使用','优惠券15天内未被使用'], fontsize =7, loc =(0.15,0.91))#添加图例 plt . title ('满减优惠形式', fontsize =15, y =1.05)#添加标题 pit . subplot (1,2,2) plt . pie ([numberThree , numberfour ], autopct ='%.1f%%', pctdistance =1.4) plt . legend (["优惠券15天内被使用","优惠券15天内未被使用"], fontsize =7, loc =(0.15,0.91))#添加图例 plt . title ('折扣率优惠形式', fontsize =15, y =1.05) #添加标题 plt . show () 报错解决
最新发布
05-24

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值