第七章(上) 递归、DFS、剪枝、回溯问题

本文详细探讨了递归问题,包括递归改迭代、机器人走网格、硬币表示、非法括号、非空子集等实例。接着讲解了深度优先搜索(DFS)的本质,如数独问题的DFS解法,并提到了部分和问题,说明DFS也可用于解决此类问题。最后,文章提到了水洼数问题,这是一个递归问题,但不需要回溯。
摘要由CSDN通过智能技术生成

其实题目四个关键字就是一个递归的问题,解决:“有多少种方案这种问题”;

递归问题

1、递归改迭代:(递归可以改成迭代,递归是自上而下的倒着想,而迭代是自下而上的一步步更新变量,其实递归和迭代,迭代要更好一点,,因为他所占的空间要少,不需要递归那样用到栈的结构而开出一大片地方来)(但递归具有更强的表达力,用几句代码表达出很复杂的关系,改成迭代则需要写很多才可以)(递归问题分为数值型和非数值型)

楼梯有n阶,小孩一次可以上1\2\3阶,计算小孩有多少种上楼方式 为防止溢出,请将结果mod1000000007

class Test48{
    static int mod = 1000000007;  //用Int就可以,java int 类型的范围是:-2147483648 到2147483648(10位)
    public static void main(String[] args) {
        
    }
    static long recursion(int n){

        if(n<0) return 0;
        if(n==0 || n==1) return 1;
        if(n==2) return 2;
        return recursion(n-1)%mod+recursion(n-2)%mod+recursion(n-3)%mod;
    }
    static int recursion2(int n){
        if(n<0) return 0;
        if(n==0||n==1) return 1;
        if(n==2) return 2;
        if(n==3) return 4;
        int x1 = 1;
        int x2 = 2;
        int x3 =4;
        for(int i=4;i<=n;i++){
            int x_1 = x1;
            x1 = x2%mod;
            x2 = x3%mod;
            x3 = ((x1+x2)%mod+x_1)%mod;
        }
        return x3;
    }
}

2、机器人走网格问题:

有一个 x×Y的网格,一个机器人走个点且只能向右或向下,要从左上角到右下角,问机器人有多少种算法,,x+y要小于等于12

关键是 f(x,y) = f(x,y-1)+f(x-1,y)

还是同样有两种写法 

class Test48{
    public static void main(String[] args) {

    }
    //倒着想
    static int solve(int x,int y){
        if(x==1 || y==1){
            return 1;
        }
        return solve(x-1,y)+solve(x,y-1);
    }
    //顺着想(但是因为是二纬的,所以保存历史数据要用二纬表来保存,但是这个存我觉得很好存哎,因为不用去拿一个变量来回换,而是直接存成二维数组)
    static int solve2(int m,int n){
        int [][]state = new int[m+1][n+1];//都从第一行或者第一列开始存,不要0的
        for(int i=1;i<=n;i++){
            state[1][i] = 1;
        }
        for(int i=1;i<=m;i++){
            state[i][1]= 1;
        }
        for(int i=2;i<=m;i++){
            for(int j=2;j<=n;j++){
                state[i][j] = state[i][j-1]+state[i][j-1];

            }
        }
        return state[m][n];
    }
}


3、硬币表示问题:

8种面值硬币 1,2,5,10,20,50,100,200 给定一个数值n

思路:在循环当中递归,每个小老板只决定最大面额的币用多少张

然后剩下的钱交给下一个去处理

这里比机器人复杂的地方在于不是一个地方要还是不要,,而是这个东西我要一个,或者我要两个,或者我要三个(在循环中递归)

class Test48{
    public static void main(String[] args) {

    }
    static int countways(int n){
        if(n<=0) return 0;
        return countwayscore(n,new int[]{1,5,10,25},3);//3表示第一次可选范围是0~3

    }
    static int countwayscore(int n,int[] coins,int cur){
        if(cur==0) return 1;
        int res =0;
        for(int i=0;i*coins[cur]<=n;i++){
            int shengyu = n-i*coins[cur];
            res+=countwayscore(shengyu,coins,cur-1);
        }
        return res;
    }
}


4、递归问题的非数值问题的解法(就是需要用容器去装了,生成一点,装一点,慢慢改变)

非法括号问题:输入n,打印n对括号的全部有效组合

import java.util.HashSet;
import java.util.Set;

class Test48{
    public static void main(String[] args) {

        Set<String> par= parenthesis(3);
        System.out.println(par);
    }
    static Set<String> parenthesis(int n){
        Set<String> s_n = new HashSet<>();
        if(n==1){
            s_n.add("()");
            return s_n;
        }
        Set<String> s_n_1 = parenthesis(n-1);
        for(String ex:s_n_1){
            s_n.add("()"+ex);
            s_n.add(ex+"()");
            s_n.add("("+ex+")");
        }
        return s_n;
    }
    //正着写
    static Set<String> parenthesis2(int n){
        Set<String> res = new HashSet<>();
        res.add("()");
        if(n==1){
            return res;
        }
        for(int i=2;i<=n;i++){
            Set<String > res_new = new HashSet<>();

            for(String e:res){
                res_new.add(e+"()");
                res_new.add("()"+e);
                res_new.add("("+e+")");
            }
            res = res_new;
        }
        retu
DFS(深度优先搜索)是一种常见的图遍历算法,它使用递归或栈的方式,从一个顶点出发,沿着一条路径一直到达最深的节点,然后回溯到上一层继续遍历其他节点。DFS常被用于解决图的连通性问题、路径问题等。在实际应用中,可以使用DFS进行状态搜索、图的遍历、拓扑排序等。 剪枝是指在搜索过程中,通过一系列的策略判断,提前终止当前搜索分支,并跳过一些无用的搜索路径,从而减少搜索时间。剪枝的核心在于提前排除某些明显不符合条件的状态,以减少无效搜索的时间开销,提高效率。在算法设计中,剪枝通常会利用一些特定的性质或条件进行判断,从而缩小搜索空间。 动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划通常用于求解最优化问题,它通过定义状态和状态转移方程,采用自底向上的思路,逐步求解每个子问题的最优值,最终得到原问题的最优解。动态规划的核心是存储已经计算过的子问题的解,避免了重复计算。 贪心算法是一种基于局部最优解的策略,它通过每一步选择在当前状态下最优的解,以期望得到全局最优解。贪心算法的基本思想是由局部最优解推导出全局最优解,通常通过贪心选择性质、最优子结构和贪心选择构成三部分。贪心算法相比其他算法,如动态规划,它的优势在于简单、高效,但缺点在于不能保证获取到全局最优解,只能得到一个近似解。 综上所述,DFS剪枝、动态规划和贪心算法在算法设计和问题求解中都发挥着重要的作用。具体使用哪种算法取决于问题的性质和要求,需要在实际应用中进行综合考虑和选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值