Java数据结构与算法笔记——递归解决数学问题的两个其他案例

递归求数的乘方

在这里插入图片描述

package recursion;

public class RecursionTest8 {
    public static void main(String[] args) {
        System.out.println(pow(2,5));
    }

    //用递归的算法实现求乘方,y不能是负数
    public static int pow(int x, int y){
        if(y == 0){//任何数的0次方是1
            return 1;
        }
        if(y == 1){//边界条件,当y等于1时,不再进行递归
            return x;
        }
        if(y%2==1){
            //奇数
            return pow(x*x,y/2)*x;
        }else {
            return pow(x*x,y/2);
        }

    }
}

递归解决组合问题

在数学中,组合是对事物的一种选择,而不考虑他们的顺序。

比如有5个登山队员,名称为 A,B,C,D和E。想要从这五个队员中选择三个队员去登峰, 这时候如何列出所有的队员组合。(不考虑顺序)。假设把从5个人中选出3个人的组合简写为(5,3), 规定 n 是这群人的大小,并且k是组队的大小。那么根据组合公式可以有: (n,k) = (n-1,k-1) + (n-1,k)

还是以递归的思想来解决:

  • 首先这五个人的组合选择三个人分成两个部分,第一部分包含A队员,第二部分不包含A队员。对于从5个人中选择 3 个人,有: (5,3) = (4,2)+(4,3) 。
  • (4,2)表示已经有A队员了,然后从剩下的4个队员中选择2个队员,(4,3)表示从5个人中剔除A队员,从剩下的4个队员中选择3个队员,这两种情况相加就是从5个队员中选择3个队员。
  • 现在已经把一个大问题转换为两个小问题了。从4个人的人群中做两次选择(一次选择2 个,一次选择3个),而不是从5个人的人群中选择3个。
  • 从4个人的人群中选择2个人,又可以表示为:(4,2) = (3,1) + (3,2)。从4个人的人群中选择3个人,又可以表示为:(4,3) = (3,2) + (3,3)。以此类推,很容易想到递归的思想。
package recursion;

public class RecursionTest10 {
    public static void main(String[] args) {
        char[] arr = new char[]{'A','B','C','D','E'};
        Comb comb = new Comb(arr);
        comb.doComb(3,0);
    }
}

class Comb{
    private char[] persons;// A B C D E
    private boolean[] selects;//选中的标记

    public Comb(char[] data){
        this.persons = data;
        selects = new boolean[data.length];
    }

    //具体实现组合的递归方法
    public void doComb(int selectNum,int index){
        //选多少人,从第几个人开始到最后的人中选
        //就是从index到最后的几个人中选择selectNum个人

        //边界
        if(selectNum == 0){
            //如果选0个人,那就没必要再分了,直接结束
            for (int i=0;i<selects.length;i++){
                if (selects[i]){
                    System.out.print(persons[i]+"  ");
                }
            }
            System.out.println();
            return;
        }
        if(index >= persons.length){
            //所有的组合都考虑完了
            return;
        }

        //递归
        //选择当前元素
        selects[index] = true;
        doComb(selectNum-1,index+1);
        //不选择当前元素
        selects[index] = false;
        doComb(selectNum,index+1);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值