前言
今天算法的内容是:数列
题解对应章节
算法零基础100讲(英雄哥著)–第二讲
第一题:剑指 Offer 64. 求1+2+…+n
题目描述
求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
难度:Medium
算法思路
总体思路:题目给予的限制很多,虽然不允许使用条件判断和乘除法,但是还有递归的思路可以一试。递归的出口条件为不断调用sum(n-1),直到n为0时返回0.
写成通俗的递归形式为
class Solution {
public:
int sumNums(int n) {
return n == 0 ? 0 : n + sumNums(n - 1);
}
};
显然下一步思路在于如何替换掉判断递归出口的三元运算符 – 利用逻辑运算符的短路特性
- 1、第一种实现思路
递归出口条件判断流程为,先判断n是否为0,不为0则继续递归调用,为0则返回0值。
而逻辑运算符&&也有类似性质,即对于 A&&B这个表达式,如果 A 表达式返回False,那么不会去执行表达式 B
利用这一特性,我们可以将判断是否为递归的出口看作 A && B 表达式中的 A 部分,递归的主体函数看作 B 部分。如果不是递归出口,则继续执行表达式 B 的部分,否则递归结束
。 - 2、第二种实现思路
同1也可利用||给出实现,即对于A || B这个表达式,如果A返回为假,才会去执行表达式B
利用这一特性,我们可以将判断是否为递归的出口看作 A && B 表达式中的 A 部分,递归的主体函数看作 B 部分。如果不是递归出口,则A的值应为False,继续执行表达式 B 的部分,否则递归结束
源码剖析
//用||实现
class Solution {
public:
int sumNums(int n) {
!n || (n+=sumNums(n-1));
return n;
}
};
//用&&实现
class Solution {
public:
int sumNums(int n) {
n && (n+=sumNums(n-1));
return n;
}
};
第二题:829. 连续整数求和
题目描述
给定一个正整数 n,返回 连续正整数满足所有数字之和为 n 的组数 。
难度:Hard
算法思路
总体思路:本题可抽象为一个等差数列求和的题目证明思路如下
核心思想:缩小k的范围防止超时;根据上图中①条件2n是k的倍数,③条件确定n的筛选条件
源码剖析
class Solution {
public:
int consecutiveNumbersSum(int n) {
int res=0;
for (int i = 1; i*i < 2*n; i++) // ①
{
if ((2*n % i) == 0 && ((2*n/i-i+1)%2) == 0) //②
{
res++;
}
}
return res;
}
};
- 1、第一处注释为循环上界
- 2、为①③条件的实现