题目描述
众所周知,牛妹非常喜欢吃蛋糕。
第一天牛妹吃掉蛋糕总数三分之一(向下取整)多一个,第二天又将剩下的蛋糕吃掉三分之一(向下取整)多一个,以后每天吃掉前一天剩下的三分之一(向下取整)多一个,到第n天准备吃的时候只剩下一个蛋糕。
牛妹想知道第一天开始吃的时候蛋糕一共有多少呢?
这道题是典型的猴子吃桃问题,只要明确一点:前一天蛋糕数量为,后一天蛋糕数量为,
方法一:迭代法
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 只剩下一只蛋糕的时候是在第n天发生的. * @return int整型 */ int cakeNumber(int n) { // write code here int x1=1,x2=0; while(n-->1){ x2=3*(x1+1)/2; x1=x2; }return x2; } };
复杂度:
时间复杂度:一层循环,时间复杂度为
空间复杂度:常数级变量,空间复杂度为
方法二:递归
递推公式为:
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 只剩下一只蛋糕的时候是在第n天发生的. * @return int整型 */ int cakeNumber(int n) { // write code here if(n==1)return 1; else return 3*(cakeNumber(n-1)+1)/2; } };
复杂度:
时间复杂度:递归深度为n,每次递归函数的复杂度为常数级,所以时间复杂度为
空间复杂度:递归运行时栈的大小不超过n,空间复杂度为
方法三:动态规划
显然,状态转移方程
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 只剩下一只蛋糕的时候是在第n天发生的. * @return int整型 */ int cakeNumber(int n) { // write code here vector<int>dp(n,0); dp[0]=1; for(int i=1;i<n;i++){ dp[i]=3*(dp[i-1]+1)/2; } return dp[n-1]; } };
复杂度:
时间复杂度:遍历一次数组,
空间复杂度:额外使用数组的大小为n,空间复杂度为