《九日集训》第十日递归

一、今日知识点总结

  1. 递归的含义:就是函数自己调用自己。

  2. 递归的三个注意点

    1).定义一个函数,这个函数会自己调用自己,但是每次传递的参数是不一样的。

    2).递归一点要有出口,即满足条件后需要return,否则就成了死递归,导致栈溢出。

    3).根据递归式来补充递归内容。(解递归问题建议都先写递推式。)

  3. 对递归深度要有个概念,深度过深会导致栈溢出。

  4. 可以采用尾递归的方式来解决,由深度造成的栈溢出。

  5. 能够使用递归来解决的问题,包含下面三个条件

    1). 待求问题的解,可以分解成几个子问题的解

    2).待求问题的解,和分解后的子问题,只有数据规模不同,求解思路完全一样。

    3).存在递归中止条件,即有出口。

二、今日做题记录

第一题

172. 阶乘后的零

给定一个整数 n ,返回 n! 结果中尾随零的数量。

提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

第一想法,先求阶乘再判断有多少了尾随零。我真这么干了。结果求阶乘的结果一直越界。阶乘的结果很大。

求因子,末尾有几个0,表示阶乘过程中乘以了几个10,二10的因子有5和2,就看存在几对5和2,偶数太多,就看包含了几个5的因子。

记录下求10以内的阶乘的递归方法

int getFactorial(int n){
    if (n <= 1){
        return 1;
    }
    return n*getFactorial(n-1);
}

求10以内的阶乘的尾递归方法

int getFactorial(int n,int res){
    if (n<=1){
        return res;
    }
    return getFactorial(n-1,n*res);
}

该题的题解

int trailingZeroes(int n){
    if(n<5){
        return 0;
    }
    return n/5+trailingZeroes(n/5);
}
第二题

1342. 将数字变成 0 的操作次数

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

就是按要求去处理num,每处理一次,结果数目加1,当num==0时就可以输出0了。

int numberOfSteps(int num){
    if(num == 0) {
        return 0;                        
    }
    if(num & 1) { //奇数同1与运算,结果为1,表示奇数。为0表示偶数
        return numberOfSteps(num-1)+1;   
    }else {
        return numberOfSteps(num/2) + 1; 
    }
}
第三题

完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

遍历整个二叉树,当子节点为空时,返回结果0,总的阶段数,等于左子树节点数+右子树节点数+本身。

int countNodes(struct TreeNode* root){
    if(root == NULL) {
        return 0;            
    }                         
    return countNodes(root->left) + countNodes(root->right) + 1;
}

第四题

LCP 44. 开幕式焰火

「力扣挑战赛」开幕式开始了,空中绽放了一颗二叉树形的巨型焰火。
给定一棵二叉树 root 代表焰火,节点值表示巨型焰火这一位置的颜色种类。请帮小扣计算巨型焰火有多少种不同的颜色。

int Hash[1024];

void transfer(struct TreeNode* root) {
    if(root) {
        Hash[root->val] = 1;       
        transfer(root->left);       
        transfer(root->right);      
    }
}
int numColor(struct TreeNode* root){
    int i, sum = 0;
    memset(Hash, 0, sizeof(Hash));
    transfer(root);
    for(i = 1; i <= 1000; ++i) {
        if(Hash[i]) ++sum;
    }
    return sum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值