美文网首页算法Java 杂谈
经典递归问题:取球问题

经典递归问题:取球问题

作者: 就良同学 | 来源:发表于2019-01-19 17:48 被阅读1次

【请先食用上一篇】:[递归与循环]](https://www.jianshu.com/p/ebd9e232f044)

问:在n个球中,任意取出m个球(不放回),求有多少种不同取法?

解法:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader scan=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入球的总数:");
        int n=Integer.parseInt(scan.readLine());
        System.out.println("请输入取出球的个数:");
        int m=Integer.parseInt(scan.readLine());
        int count=f(n,m);
        System.out.println("在"+n+"个球中,任意取出"+m+"个球(不放回),有:"+count+" 种不同取法");
    }
    private static int f(int n, int m) {
        if(m > n){
            return 0;
        }
        if (n == m) {
            return 1;
        }
        if (m == 0) {
            return 1;
        }
        return f(n-1,m-1)+f(n-1,m);
    }
}

运行截图

image

思路

【分析】:

递归问题,往往是将问题拆解成一个与原问题相似的问题+一个现阶段容易且能够解决的小部分,如图所示:

image

假设左边阶梯型图形为给出的问题,解法是转化为右边图形:将原问题拆解为与原问题相似的蓝色上部分以及现阶段容易且能够解决的绿色部分

但有时候所给出的问题往往难以直接拆分,这类问题如同一个完美无缺的圆,突破口不易观察,很难直接将问题进行拆解,正如这道取球问题,这时就需要花点技巧。

image

【解决】:

我们假设n个球中有一个为幸运球,这时取球问题就出现了两种情况:

  • 幸运球一定被取出:有了这个限定条件,相当于从n个球中拿出一个球(幸运球)事先放在取球者手中(这样才能保证幸运球一定被取出),此时取球问题就变成了从n-1个球中取出m-1个球,即f(n-1,m-1)
  • 幸运球一定不被取出:有了这个限定条件,相当于从n个球中剔除出一个球(幸运球),这样才能保证幸运球一定不被取出,此时取球问题就变成了从n-1个球中取出m个球,即f(n-1,m)

综上,从n个球中取出m个球的总取法=取法1(幸运球被取出)+取法2(幸运球不被取出)=f(n-1,m-1)+f(n-1,m).

这便满足了递归问题两大要点之一:相似性,还需要满足另一要点:出口,如下:

  1. if (m > n) return 0;//取球数>总球数,不合理,终止递归
    
  2. if (n == m) return 1;//表示从x个球中取出x个球,只有一种取法
    
  3.  if (m == 0) return 1;//表示从x个球中取出0个球,也是只有一种取法(即不取)
    

相关文章

  • 经典递归问题:取球问题

    【请先食用上一篇】:[递归与循环]](https://www.jianshu.com/p/ebd9e232f044...

  • 取球问题

    从N个不同的球中取出M个,求有多少种取法。 问题分析 这里显然可以通过数组合公式求出答案,但这里笔者讲一下递归的版...

  • LeetCode-N Queens

    N皇后问题。经典回溯问题: 以下是递归及非递归的方法:

  • 第二章 递归和回溯

    递归 递归的含义:任何调用自身的函数称为递归。用递归求解问题要点在于递归函数调用自身取解决一个规模比原始问题小一些...

  • 经典递归问题(2)

    反转串 求一个字符串相应的反转串。 杨辉三角 计算3个A、2个B可以组成多少种排列的问题(如:AAABB,AABB...

  • 经典递归问题(1)

    组合问题递归解 在n个球中,任意取出m个(不放回),求有多少种不同取法。 思路:从题目上看,这问题对于递归来说似乎...

  • 递归经典问题求解

    算法实现全部使用java或者伪代码!!! 1.数组求和 想到数组求和,大家肯定想到的是遍历求和 还可以使用递归的方...

  • 递归经典问题求解

    2.字符串相关操作 java 类 String 中对字符串的操作特别之多 如通过equal()判断字符串相等 tr...

  • 经典递归问题:全排列问题

    【题目】设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。 【算法讲解】: 设R={r1,r2,…,r...

  • 2.2 递归经典问题:汉诺塔问题

    Chapter2: 时间复杂度分析、递归、查找与排序 2. 递归经典问题:汉诺塔问题 问题 有A,B,C三个柱子,...

网友评论

    本文标题:经典递归问题:取球问题

    本文链接:https://www.haomeiwen.com/subject/uduzdqtx.html