#region 暴⼒递归 时间复杂度是(O(2^n)) /* 这里面存在巨大的浪费 只有 f(n - 1) + f(n - 2) ⼀ 个加法操作,时间为 O(1)。 * 这个算法的时间复杂度为 O(2^n),指数级别,爆炸 * 观察递归树,很明显发现了算法低效的原因:存在⼤量重复计算 * 重叠⼦问题要去掉 //fib(6) = fib(5) + fib(4)==>5+3 //fib(5) = fib(4) + fib(3)==>5 //fib(4) = fib(3) + fib(2)==>3 //fib(3)=fib(2) + fib(1) ==>2 //fib(2)=1 //fib(1)=1 */ static int fib1(int N) { if(N == 1 || N == 2) return 1; return fib1(N - 1) + fib1(N - 2); } #endregion #region 带备忘录的递归解法 static int fib2(int N) { if (N < 1) return 0; int[] memo = new int[N + 1]; // 初始化最简情况 return helper(memo, N); } static int helper(int[] memo, int n) { if (n == 1 || n == 2) return 1; // 已经计算过 if (memo[n] != 0) return memo[n]; memo[n] = helper(memo, n - 1) + helper(memo, n - 2); return memo[n]; } #endregion #region dp 数组的迭代解法 //循环处理 static int fib3(int N) { int []dp = new int[N+1]; dp[1] = dp[2] = 1; for (int i = 3; i <= N; i++){ dp[i] = dp[i - 1] + dp[i - 2]; } return dp[N]; } #endregion
//方程拆解法:
static int fib4(int n) { if (n == 2 || n == 1) { return 1; } //prev上一个 ,curr当前的 int prev = 1, curr = 1; for (int i = 3; i <=n; i++) { /*1,1,2,3,5,8 第一步:2=1+1 第二步:prev=curr;(prev=1) 第三步:curr=sum;(curr=2) */ int sum = prev + curr; prev = curr; curr = sum; } return curr; }
class Program { static void Main(string[] args) {
//直接跑起来 //1、1、2、3、5、8、13 Console.WriteLine("Hello World!"); //fib(6) = fib(5) + fib(4)==>5+3 //fib(5) = fib(4) + fib(3)==>5 //fib(4) = fib(3) + fib(2)==>3 //fib(3)=fib(2) + fib(1) ==>2 //fib(2)=1 //fib(1)=1 //var val = fib(6); //Console.WriteLine("val:" + val); //var val = fib2(6); //Console.WriteLine("val:" + val); var val = fib2(6); Console.WriteLine("val:" + val); } }