查找列表唯一重复元素时N*(N-1)/2公式生效原因咨询
核心原因
你算错的根本原因是套求和公式时没对应上实际的元素范围,两个公式本身都没问题,只是用错了参数。
逻辑拆解
从你给的两个测试用例就能反推出这道题的列表规则:
- 当列表长度为
length时,原本的不重复元素是从1到length-1的连续自然数,一共length-1个 - 恰好有一个数多出现了一次,所以最终列表长度刚好是
(length-1)+1 = length
比如你举的两个测试用例长度都是4,对应的不重复元素就是1、2、3三个数,多一个重复数之后总长度就是4,完全符合规则。
我们常用的前k个从1开始的连续自然数求和公式是标准形式:sum(1到k) = k*(k+1)/2。你之前错就错在直接把列表总长度length当成了公式里的k,相当于默认不重复元素是1到4,那算上重复元素列表总长度应该是5才对,和你实际的用例长度对不上,结果当然错。
把正确的k值——也就是不重复元素的最大值length-1——代进标准公式算一下:sum(1到length-1) = (length-1)*((length-1)+1)/2 = length*(length-1)/2
你以为的“特殊变体公式”,其实就是把正确参数代入标准公式之后化简出来的结果,根本不是什么例外情况。
用例验证
拿你的测试用例套进去算就很清楚:
- 列表长度为4,理论上不重复元素的和是
4*(4-1)/2 = 6- 数组
[1,2,3,3]实际和是9,差值9-6=3,就是重复的3 - 数组
[1,1,2,3]实际和是7,差值7-6=1,就是重复的1
- 数组
结果完全正确。
小优化建议
你代码里的绝对值其实没必要加:因为数组总和就是不重复元素的和再加一次重复的数,所以数组和一定比理论值大,直接做差就行,加了abs也不影响结果。另外建议把浮点数运算换成整数整除,避免精度问题,写法更稳妥:
class Solution: def solve(self, nums): listSum = sum(nums) length = len(nums) expected = length * (length - 1) // 2 return listSum - expected
内容的提问来源于stack exchange,提问作者Wadu Hek
相关产品推荐
相关产品推荐

