• 算法入门 | 分治策略


    目录

    分治策略

    1.分治法可以解决的问题特征

    2.分治法解题步骤

    3.分治法编程举例

    递归求阶乘

    求斐波那契数列

    小练习:给出一个数n,打印其每一位


    分治策略

    1.分治法可以解决的问题特征

    (1)问题规模缩小到一定程度就可以轻易解决

    (2)问题可以分解为若干个规模较小的相同类型问题

    (3)使用小规模的解可以合并成该问题原规模的解

    (4)该问题分解出的各个子问题相互独立

    2.分治法解题步骤

    (1)分解:将原问题划分为与原问题形式相同的子问题,只是规模减小。

    (2)解决:递归求解子问题,如果子问题规模足够小则停止递归,直接求解。

    (3)合并:将小规模的解合并为原规模问题的解。

    3.分治法编程举例

    递归求阶乘

    (1)思想:不断缩小问题规模(要求n的阶乘,先求n-1的阶乘;要求n-1的阶乘,先求n-2的阶乘......)直至规模为1~求1的阶乘,再逐层返回合并解。

    递归定义式如图: 

    (2)代码实现(循环实现):

    1. int fac(int n)
    2. {
    3. if (n <= 1) return 1;
    4. int sum = 1;
    5. for (int i = 2; i <= n; ++i)
    6. {
    7. sum *= i;
    8. }
    9. return sum;
    10. }
    11. int main()
    12. {
    13. int n = 0;
    14. cin >> n;
    15. cout << fac(n) << endl;
    16. return 0;
    17. }

     时间复杂度:O(n)       空间复杂度:S(1)

    (3)代码实现(递归实现):

    1. int fac(int n)
    2. {
    3. if (n <= 1) return 1;
    4. return n * fac(n - 1);
    5. }
    6. int main()
    7. {
    8. int n = 0;
    9. cin >> n;
    10. cout << fac(n) << endl;
    11. return 0;
    12. }

    时间复杂度:O(n)       空间复杂度:S(n)

    由于递归会开辟栈帧,故有额外空间开辟:空间复杂度S(n)

    (4)补充:没有无限递归!!栈的空间是有限的,栈满会溢出。

    求斐波那契数列

    (1)思想:斐波那契数列(1 1 2 3 5 8 12 21.....),递归求解。当n>2时,fib(n)=fib(n-1)+fib(n-2);

    递归定义式如图: 

    (2)代码实现(循环实现):

    1. int fib(int n)
    2. {
    3. int a = 1, b = 1, c = 1;//c初值为1,避免写n==1||n=2时return 1
    4. //if(n==1||n==2) return 1;
    5. for (int i = 3; i <= n; ++i)
    6. {
    7. c = a + b;
    8. a = b;
    9. b = c;
    10. }
    11. return c;
    12. }
    13. int main()
    14. {
    15. int n = 0;
    16. cin >> n;
    17. cout << fib(n) << endl;
    18. return 0;
    19. }

    (3)代码实现(递归实现):

    1. int fib(int n)
    2. {
    3. if (n == 1 || n == 2) return 1;
    4. return fib(n - 1) + fib(n - 2);
    5. }
    6. int main()
    7. {
    8. int n = 0;
    9. cin >> n;
    10. cout << fib(n) << endl;
    11. return 0;
    12. }

    时间复杂度:O(n)       空间复杂度:S(n)

    小练习:给出一个数n,打印其每一位

    (1)代码实现(循环实现):

    1. void PrintInt(int n)
    2. {
    3. if (n < 0) return;
    4. while (n != 0)
    5. {
    6. printf("%d ", n % 10);
    7. n /= 10;
    8. }
    9. }
    10. int main()
    11. {
    12. int n = 0;
    13. cin >> n;
    14. PrintInt(n);
    15. return 0;
    16. }

    (2)代码实现(递归实现):

    1. void PrintInt(int n)
    2. {
    3. if (n <= 0) return;
    4. printf("%d ", n % 10);
    5. PrintInt(n / 10);
    6. }
    7. int main()
    8. {
    9. int n = 0;
    10. cin >> n;
    11. PrintInt(n);
    12. return 0;
    13. }
  • 相关阅读:
    【Java系列】深入解析 Lambda表达式
    【大话Presto 】- 核心概念
    Android学习笔记 1.2.7 自定义任务 && 1.2.8 自定义插件
    Linux之SSH、rsync
    小趴菜教你如何用Python开发手机App..
    Vue项目的记录(五)
    Nginx重定向
    VAN LKA、LSKA
    教程分享:mp3语音转文字免费方法有哪些?
    Spring事务、设计模式以及SpringBoot自动装配原理
  • 原文地址:https://blog.csdn.net/m0_56194716/article/details/127737842