求数组平衡点的问题

整形数组平衡点问题:平衡点指左边的整数和等于右边的整数和,
求出平衡点位置,要求输入的数组可能是GB级

算法分析:
1)如果可以使用高精度数字,那就先求出数组的数字总和,然后从数组左端开始累加,找到其和等于数组总和1/2倍的子数组,此子数组的长度就是一个平衡点。比如数组为 [2, 1, 3, -4, 1, 3],那么求出平衡点为2和5,表示数组左边两个数字之和等于右边6-2个数字之和;数组左边5个数字之和,等于右边6-5个数字之和。
2)如果不能使用高精度数字,那就要考虑整数溢出的问题,实际上任何两个同符号整数相加都有可能溢出,何况是上GB的数据呢。

基本的思想還是一样的,从数组左端开始寻找其和等于数组总和两倍的子数组,只是要避免让两个同符号数相加或者两个异符号数相减。使用数学公式上的小技巧:如果x+y+z=2x+2y,则z=x+y。

设原数组为A,假设存在一个数组AA,每个元素都是A中对应元素的两倍。

假设数组里都是正数,那只要用类似于归并的方法,从A和AA的最左端开始依次相互抵消,比如:
A = [5, 8, 13], AA = [10, 16, 26]
那么先拿5和10比较,用大的减去小的,丢掉小的,结果这两个数组就变成:
A = [8, 13], AA = [5, 16, 26]
然后在用8和5比,大的减去小的,丢掉小的,得到:
A = [3, 13], AA = [16, 26]
以此类推:
A = [13], AA = [13, 26]
A = [], AA = [26]
到这个时候,A已经为空了,而AA恰好减少了左边两个元素(第三个元素还没有被减小),所以原数组中左边两个数字之两倍和等于原数组数字总和。这便是唯一的一个平衡点。

如果数组里有正数也有负数,可以先让A中的正负数相互抵消直至其中的一种数全部消失(假设负数全部消失);而对于AA,遇到正数与A相消,遇到负数则内部相消(显然AA中的负数迟早会被消灭光)。当A为空时,如果AA恰好减少了左边若干个元素(可能有正有负),那这就是第一个平衡点。
由于负数的存在,这个平衡点右边可能还会有其他平衡点,那么只要让AA中的正负数继续相互抵消,直到再次出现恰好减少了左边若干个元素的时候,就又得到了一个新的平衡点。

注意两点:
1、一个整数乘以2是有可能溢出的,所以实际的代码中不能做乘法,但可以有其他变通的方法。
2、注意0这个讨厌的家伙,一个平衡点右边的数字如果是0,那么这里也是一个平衡点。

伪码:
01. AA <- A * 2
02. while A中有正数 and A中有负数:
03. A中正负数相互抵消
04. // 假设A中没有负数了
05. while A不为空:
06. AA中正数与A中数字相互抵消
07. while true:
08. if AA恰好减少了左边m个元素:
09. m是一个平衡点
10. m右边连续的0都是平衡点
11. if AA为空
12. break
13. if AA中有负数:
14. AA中正负数相互抵消
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值