06 递归与分治

一、递归

递归就是将一个问题拆解成解决方案完全相同的子问题,并且有一个明确的终点

 从哪来到哪去 D运行结束回到C 然后回到B然后回到A

1.斐波那契数列

        斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契,以子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34、55……在数学上,这一数列以如下递推的方法定义:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。

解法一:递归

#include<stdio.h>

unsigned int FB(unsigned int n)
{
    if(n==0)return 0;
    if(n==1||n==2)return 1;
    return FB(n-1)+FB(n-2);
}

int main()
{
    unsigned int fb = FB(40);
    printf("%u\n",fb);
    return 0;
}

解法二:优化后的

即在原本的基础上  对上一次的运算结果进行一个存储 防止再次重复计算

#include<stdio.h>

unsigned int FB2(unsigned int n)
{
    if(n==0)return 0;
    if(n==1||n==2)return 1;
    int a=1,b=1,c=0;
    for(int i=3;i<=n;i++)
    {
        c=a+b;
        a=b;
        b=c;
    }
    return c;
}

int main()
{
    unsigned int fb = FB2(40);
    printf("%u\n",fb);
    return 0;
}

解法三:矩阵

 

 2.跳台阶问题

其实跟斐波那契数列是一个问题  就是初值有所不同

class Solution {
public:
    int numWays(int n) {
            if(n==0||n==1){
                return 1;
            }
            if(n==2)
            {
                return 2;
            }
            int a=1,b=2,c=0;
            for(int i=3;i<=n;i++)
            {
                c=(a+b)%1000000007;//答案需要取模 1e9+7(1000000007)
                a=b;
                b=c;
            }
            return c;
    }
};

3.汉诺塔问题

这个问题来源于印度。有三个金刚石塔,第一个从小到大摞着64片黄金圆盘。现在把圆盘按大小顺序重新摆放在最后一个塔上。并且规定,在小圆盘上不能放大圆盘,在三个塔之间一次只能移动一个圆盘。

 二、分治

分治法:分而治之 将一个问题拆解成若干个解决方法相同的子问题

分治法需要满足四点:

  1. 问题难度随着数据规模缩小而降低
  2. 问题可拆分
  3. 子问题之间相互独立
  4. 子问题的解可以合并

2.二分查找 BinaryChop

折半搜索,首先的要求就是 有序,

方法步骤为

  1. 先找到中间元素mid
  2. 让mid与要寻找的值target进行比较
  3. 如果mid>target那么搜索范围就变成(Begin,Mid-1)
  4. 如果mid<target那么搜索范围就变成(Mid+1,End)
  5. int BinaryChop(int arr[],int nBegin,int nEnd,int target)
    {
        if(arr==NULL||nBegin>nEnd)return -1;
        
        int nMid;
    
        while(nBegin<nEnd)
        {
            nMid=nBegin+(mEnd-nBegin)/2;
            
            if(arr[nMid]==target)
            {
                 return nMid;
            }
            else if(arr[nMid]>target)
            {     
                nEnd=nMid-1;
            }        
            else
            { 
                nBegin=nMid+1;
            }    
        }
        return -1;
    }
    int BinaryChop(int arr[],int nBegin,int nEnd,int target)
    {
        if(arr==NULL||nBegin>nEnd)return -1;
        
        int nMid=nBegin+(nEnd-nBegin)/2;
    
    
        if(arr[nMid]==target)
        {
            return nMid;
        }
        else if(arr[nMid]>target)
        {     
            return BinaryChop(arr,nBegin,nMid-1,target);
        }        
        else
        { 
            return BinaryChop(arr,nMid+1,nEnd,target);
        }    
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值