递归和动态规划法对比

下面用LeetCode上的一个爬楼梯问题给出递归和分治两种解法来对比。

假设你正在爬楼梯,需要n阶才能到达楼顶(n是一个正整数),每次你可以爬1或2个台阶,有多少种不同的方法可以爬到楼顶?

这个问题每走3阶就要重新选择爬1阶或者两阶,很明显我们可以把一个大问题拆解成一个一个的小问题,可以使用递归来解决。
递归方程式:f(n) = f(n-1)+f(n-2)
递归的结束条件是我们已知的:f(1) = 1; f(2) = 2;
代码如下:

int upStairs1(int n) {
    
    if (n < 1) return 0;
    if (n == 1) return 1;
    if (n == 2) return 2;
    
    return upStairs1(n-1)+upStairs1(n-2);
}

使用动态规划法,开辟n+1个内存空间来存储每一步的值:

int upStairs2(int n) {
    
    if (n == 1) return 1;

    int *times = (int *)malloc(sizeof(int)*(n+1));
    times[0] = 0;
    times[1] = 1;
    times[2] = 2;

    for (int i = 3; i < n+1; i++) {
        times[i] = times[i-1]+times[i-2];
    }
    
    return times[n];
}

两种算法的时间复杂度:递归的时间复杂度是n的平方,分治法复杂度为n。从空间角度来看,使用递归,多个函数嵌套调用,系统会开辟一个“递归工作栈”作为整个函数运行期间的数据存储,空间上的耗费是很大的,而分治法则只需要开辟一段存储空间来存储整形数据。综合来看,我们还是要尽量避免递归的使用。动态规划法是个很好的选择。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。