最近一直看编程之美,想法真的很重要,今天发这篇文章还是有一点不自信,希望碰到志同道合的同学一起讨论下!
本文来自:http://blog.csdn.net/lengzijian/article/details/7842551
题目:
有一个无序、元素个数为2n的正整数数组,要求:如何能吧这个数组分割为元素个数为n的两个数组,并使两个子数组的和最近?
例如有如下数组如图:
第一行:源数组
第二行:目的数组
书中讲了很多方法,这里就不在赘述了,我的方法也很简单,相信很多人也想到了,但是没有办法证明这个方法的可靠性。今天我们主要讲下,该方法的可靠性。
先来说下方法:
1. 首先对无序数组进行排序(时间复杂度nlogn)
2. 从当前源数组中取最大的元素,放置到一个和最小的目的数组中(起初都为0,故可以随意放置),同时这个最大元组从源数组中删除。
3. 重复第2步,直到源数组个数为0
按照如上方法:上题的到的结果为:
左边和为43,右边为44。符合题意。
很多人第一感觉就是,①题目不会这么简单,②这种解法可能会有漏洞,下面对该种解法,做一下个人的理解。
1. 我把这种问题看作是往天平上放筹码,放到最后的要求是天平两端的差异最小;
2. 先把要放的筹码都排好序;
3. 先放置最大筹码到天平的任意一段(起初天平是平衡的);
4. 放置第二块筹码到天平筹码重量轻的一段;
5. 放置第三块筹码到天平筹码轻的一段(一定是和第二块一起)。这时,有两种可能:①:天平没有动,此时应按照规则继续放下一块;②天平平衡有变化(包括两边平衡和逆变化),我们可以确定的是,此时此刻天平两边的筹码重量差一定小于等于刚刚放上的筹码(目前天平上最轻的筹码)
6. 按照上面的方法,放到最后一块后,如果天平平衡是有变化的,我们可以保证天平量变的差值永远小于等于所有筹码最小的一个。当没有变化是,也可以保证我们的结果是正确的(自己考虑下)
目前我能想到的只有这些,根据上面的规则时间复杂度应该为nlogn(排序)+n = O(nlogn)
如果本人哪里说得不对,可以留言,也希望能够遇到一些朋友一起讨论下这方面的问题。