1.阶乘后的零
给定一个整数
n
,返回n!
结果中尾随零的数量。提示n! = n * (n - 1) * (n - 2) * ... * 3 *
int trailingZeroes(int n){
if(n < 5)
return 0;
return n / 5 + trailingZeroes(n / 5);
}
//求n的阶乘后面0的个数,求10的因子,
//2 * 5 含2的倍数肯定大于5
//f(n) = n / 5 + n / 25 + n / 125 + n / 625 ...
//n/5 是有多少个5的倍数
//n/25 是有多少个25的倍数 = 个数乘以2是有多少个5的倍数
//n/125是有多少个125的倍数= 个数乘以3是有多少个5的倍数
//若n能除125,则n/5的个数中包含一份25的和一份125,则n/25 中包含125的
//所以一直加起来就能得到n / 5 < 5 时,将前面的全部加起来就得到了阶乘后的零
给你一个非负整数
num
,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。
int numberOfSteps(int num){
if(num == 0)
return 0;
if(num & 1){
return 1 + numberOfSteps(num - 1);
}
else{
return 1 + numberOfSteps(num / 2);
}
}
//一个数按位与1等于1时,这个数是奇数,一个数按位与1等于0时,这个数是偶数
//使用递归 :
// 当数字为0,不需要操作,返回0
// 当数字为奇数,操作次数为1 + (num - 1)需要操作的次数
// 当数字为偶书时,操作次数为1 + (num / 2 )需要的次数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int countNodes(struct TreeNode* root){
if(root == NULL){
return 0;
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
//当根指针为空指针时,节点的个数为0
//当根指针不是空指针时,节点的个数为1 + 这个节点下左边的个数 + 这个节点右边的个数
4.开幕式焰火
「力扣挑战赛」开幕式开始了,空中绽放了一颗二叉树形的巨型焰火。
给定一棵二叉树 root 代表焰火,节点值表示巨型焰火这一位置的颜色种类。请帮小扣计算巨型焰火有多少种不同的颜色
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int Hash[1001];
void transfer(struct TreeNode *root){
if(root){
Hash[root->val] = 1;
transfer(root->left);
transfer(root->right);
}
}
int numColor(struct TreeNode* root){
int i = 0, sum = 0;
memset(Hash, 0, sizeof(Hash));
transfer(root);
for(i = 0; i < 1001; i++){
if(Hash[i]){
sum++;
}
}
return sum;
}
//计算开幕式焰火的类型,不同的值代表不同焰火
//先设置一个哈希数表,将其全部设置为0,然后遍历二叉树,将二叉树的那个值对应的下标的数字设为,非零,统计数组中非0的个数就能得到焰火的类型
//当指针为空指针时,表示后面没有节点,在往下走没有数字,终止
5.整数替换
给定一个正整数 n ,你可以做如下操作:
如果 n 是偶数,则用 n / 2替换 n 。
如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。
n 变为 1 所需的最小替换次数是多少?
int integerReplacement(int n){
if(n == 2147483647)
return 32;
// (long)n;
if(n == 1)
return 0;
if(n & 1){
if((n & 3) == 3 && n != 3){
return 1 + integerReplacement(n + 1);
}
else
return 1 + integerReplacement(n - 1);
}
else{
return 1 + integerReplacement(n / 2);
}
}
//当n为2147483647时,加1时会造成数组越界,所以直接返回这个值
//当n是奇数,且是3的倍数时,进行的操作是加1,否则为减1
//当n是偶数,进行操作是除2;
//n为奇数时,可以直接进行两部操作,重新变成一个数
//(n + 1) / 2 (n - 1 ) / 2 把这个数变成偶数要好一些
//奇数的公式 : 2n + 1 带入的结果是 n + 1或 n ,结果奇偶性取决于n的奇偶性
// 不妨令 n = 2k 或 2k + 1代表奇偶
// 带入后式子为:原数为 4k + 1 或 4k + 3
// 就可以转换,4k + 3 时,加1,4k + 1时,减1
// 当为3时,直接减一除2
//当n % 4 = 1 时,
// n应该变为 n - 1
//当n % 4 = 3 时
// n应该变为 n + 1
// 7 -- 8 -- 4 -- 2 -- 1
// 7 -- 6 -- 3 -- 2 -- 1
// 11 -- 12 -- 6 -- 3 -- 2 -- 1
// 11 -- 10 -- 5 -- 4 -- 2 -- 1
// 15 -- 16 -- 8 -- 4 -- 2 -- 1
// 15 -- 14 -- 7 -- 8 -- 4 -- 2 -- 1
n为4k + 1时,最好-1(2k) -- k(3);假设加1
经过两次变换后 : 2k + 1 2
加一 :(k + 1) 4(减一得到这个结果是4步)
减一 :(k) 4(减一得到这个结果是3步)
n为4k + 3时,最好+1;假设减一
经过两次变换后:2k + 1
加一 :k + 1(4)(加一需要3步)(2k + 1 ---- k + 1)
减一 :k (4)(加一需要4步)(2k + 1 ---- 2k --- k)
给定二叉搜索树的根结点
root
,返回值位于范围[low, high]
之间的所有结点的值的和。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int rangeSumBST(struct TreeNode* root, int low, int high){
if(root == NULL){
return 0;
}
if(root->val > high){
return rangeSumBST(root->left, low, high);
}
if(root->val < low){
return rangeSumBST(root->right, low, high);
}
return root->val + rangeSumBST(root->left, low, high) + rangeSumBST(root->right, low, high);
}
//求符合条件的二叉搜索数的和,
//二叉树的左边是递减的,右边是递增的,
//只要那个数比最大的大,就从左边找符合条件的
//只要那个数比最小的小,就从右边找符合条件的
//返回所有符合条件数的和
7.二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int maxDepth(struct TreeNode* root){
if(root == NULL){
return 0;
}
int left = maxDepth(root->left);
int right = maxDepth(root->right);
if(left > right){
return left + 1;
}
return right + 1;
}
//如果是空指针,返回0;
//如果左边的深度大于右边,深度就是左边+1
//若果右边的深度大于左边,深度就是右边+1
8.二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int maxDepth(struct TreeNode* root){
if(root == NULL){
return 0;
}
int left = maxDepth(root->left);
int right = maxDepth(root->right);
if(left > right){
return left + 1;
}
return right + 1;
}
9.翻转二叉树
翻转一棵二叉树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* invertTree(struct TreeNode* root){//函数返回的是结构体指针root
if(root == NULL){//如果是空指针,返回0;
return 0;
}
struct invertTree *left = invertTree(root->left);//将root->left 的指针赋给left
struct invertTree *right = invertTree(root->right);//将root->right的指针赋给right
root->left = right;//交换位置
root->right = left;//
return root;
}
10.所有路径
给定一个有 n 个节点的有向无环图,用二维数组 graph 表示,请找到所有从 0 到 n-1 的路径并输出(不要求按顺序)。
graph 的第 i 个数组中的单元都表示有向图中 i 号节点所能到达的下一些结点(译者注:有向图是有方向的,即规定了 a→b 你就不能从 b→a ),若为空,就是没有下一个节点了。
11.所有路径
给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)
二维数组的第 i 个数组中的单元都表示有向图中 i 号节点所能到达的下一些节点,空就是没有下一个结点了。
译者注:有向图是有方向的,即规定了 a→b 你就不能从 b→a 。