829. 连续整数求和
输入: n = 5
输出: 2
解释: 5 = 2 + 3,共有两组连续整数([5],[2,3])求和后为 5。
做完之后看到大家都是使用奇约数的方法,还是很兴奋的。
官网的解法,实在是太复杂了。
然后通过不断的优化,执行用时:40 ms, 在所有 Python3 提交中击败了98.53%的用户。
from itertools import combinations
class Solution:
def consecutiveNumbersSum(self, n: int) -> int:
temp = n
factors = []
# 寻找所有的因数
square = n ** 0.5
min_factor = 2
while n != 1:
if n % min_factor == 0:
# 删除所有的因子2
if min_factor != 2:
factors.append(min_factor)
n = n // min_factor
square = n ** 0.5
else:
min_factor += 1
if min_factor > square:
factors.append(n)
break
# print(factors)
def multiply(arr):
res = 1
for v in arr:
res *= v
return res
all_divisor = set()
for i in range(len(factors)+1):
for c in combinations(factors, i):
all_divisor.add(multiply(c))
# return
# 加入n满足m个连续整数之和
# 如果m为奇数, 那么 n % m = 0
# 如果m为偶数,那么 n / m = X.5
# 若x为n的因子
# 若x为奇数,则中间数字为n // x
# 中间偏左1数为 mid_left = n // x - 1
# 中间分开,左边的数字有 num_left = (x - 1) // 2
# 要求 mid_left >= num_left (因为需要为正整数)
# mid = x / 2
# num = n / (x / 2)
# mid_left = mid / 2 - 0.5 # 中间靠左的数
# num_left = num / 2
# 要求 mid_left >= num_left (因为需要为正整数)
count = 0
# print('all_divisor')
# print(all_divisor)
n = temp
for x in all_divisor:
if n % x == 0:
# print(x)
mid = n // x
mid_left = n // x - 1
num_left = (x - 1) // 2
if mid_left >= num_left:
# print('mid:' + str(mid))
count += 1
mid = x / 2
num = n / (x / 2)
mid_left = mid - 0.5
num_left = num / 2
if mid_left >= num_left:
# print('mid:' + str(mid))
count += 1
return count