思路:
题目的主要信息:
- 每天吃掉蛋糕总数的1/3,再额外吃1个
- 吃到第n天还剩下1个蛋糕,问最开始总共有多少蛋糕
这是一个数学问题,可以用递归、动态规划、迭代处理。
方法一:递归
具体做法:
第n天还剩下1一个蛋糕,那么总蛋糕数就是n-1的子问题+1的3/2,可以写出如下递归:
class Solution { public: int cakeNumber(int n) { if(n == 1) //1和2单独讨论 return 1; if(n == 2) return 3; return 3 * (cakeNumber(n - 1) + 1) / 2; //返回子问题+1的3/2 } };
复杂度分析:
- 时间复杂度:,递推公式:
- 空间复杂度:,最大递归树的深度为
方法二:动态规划
具体做法:
用递归解决的问题,我们也可以用动态规划。借助辅助数组,表示第天吃完后还剩余多少蛋糕,,借助方法一递归的公式往前计算即可。
class Solution { public: int cakeNumber(int n) { vector<int> dp(n, 0); //dp[i]表示第i天吃完后还剩余多少蛋糕 dp[n - 1] = 1;//第n天刚好要吃的时候剩余1,即n-1天吃完后为1 for(int i = n - 2; i >=0; i--) dp[i] = 3 * (dp[i + 1] + 1) / 2; return dp[0]; //第0天吃完还剩余多少即没吃的时候总数为多少 } };
复杂度分析:
- 时间复杂度:,一次遍历
- 空间复杂度:,辅助数组dp的空间
方法三:迭代
具体做法:
仔细观察方法二的动态规划,每次只用到了的数据,然后依次往前遍历。因此我们可以用一个常量代替数组,每次只需要更新常量即可。
class Solution { public: int cakeNumber(int n) { int res = 1; for(int i = n - 2; i >=0; i--) res = 3 * (res + 1) / 2; //公式并更新res return res; } };
复杂度分析:
- 时间复杂度:,一次遍历
- 空间复杂度:,常数个变量