题目
给定一个正整数 n,返回 连续正整数满足所有数字之和为 n 的组数 。
思路
1、暴力枚举
①思路是将1-n整个区域通过中位数划分为左半区域和右半区域,右半区域舍去(中位数右边都是大于中位数的数值,若大于中位数的几个数相加的和不可能等于n),只用左半区域。
②设置答案初始值ans =1(因为自己可以等于自己),判断n是奇数还是偶数
- 奇数:1-n序列间的中位数加上中位数右边以为数值肯定等于n,于是ans+1,指针跳到中位数左侧枚举前面每一位数和前面所有数的和,看是否能找到和为n的序列。
- 偶数:1-n序列中位数左右无法找到和其匹配和等于n,ans不变,指针跳到中位数左侧枚举前面每一位数和前面所有数的和,看是否能找到和为n的序列。
2、数学方法
思路是列举序列长度为1-n的所有序列,判断n是否在序列之中。
具体做法是求出每个序列的首项S1, 如果(N-S1)mod k==0,那么说明N处在这个序列中,因为是单调递增,所以只能出现一次,计数器加一。
每个序列都是等差序列,高中所学的数学知识现在用上了,如果子序列长度为K,那么首项S1=SUM(1~k)。
题解
一、暴力枚举(会超时)
# 829. 连续整数求和 def consecutiveNumbersSum(n: int) -> int: if n == 1: return 1 ans = 1 if n % 2 != 0: ans += 1 res = n // 2 while res >= 1: temp = 0 for i in range(res, 0, -1): temp += i if temp == n: ans += 1 res -= 1 break if temp > n: res -= 1 break if temp < n: res -= 1 return ans
二、数学方法
def consecutiveNumbersSum(self, N: int) -> int: if N<=2: return 1 c=0 for x in range(1,N): s=x*(x+1)//2 if s<N: if (N-s)%x==0: c+=1 elif s==N: c+=1 break else: break return c