简单leetcode(五)

102. Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes’values. (ie, from left to right, level by level).

For example: Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7

return its level order traversal as:
[
[3],
[9,20],
[15,7]
]

给定一个二叉树,写出层次遍历的数组形式。

初见这个问题有些懵,后来才发现,自己对于树是多么的陌生。所以浪费了大量的时间,感觉做出这个题用了大概两天的时间,思路很早就会了,但是还是bug调到最后,也懒的在本地电脑上调试,因为感觉这不是办法,需要练会看简单程序逻辑的方法,另外调试还得自己建树,麻烦。(真心是为自己的蠢给跪了,愈挫愈勇吧。)

做这道题,经历了这样的思维

  1. 有点懵没有思路
  2. 可以层次遍历,但是怎么通过遍历获得上面数组的形式不知道
  3. 既然需要动态申请数组,那么在申请之前至少需要知道申请的数组的大小
  4. 可以先写个函数获得数的深度,也就是确定的返回数组的行数组的大小,另外通过一个数组记录各层的节点的数目,然后通过把树以层次遍历的顺序存储到数组中,其中每个节点都要记录,没有就是null,这样数组每行就可以确定,然后通过记录的各层节点的数量,再把这个数组转换成需要的数组的形式,也就是去掉其中null。(叙述完毕,我连自己都不知道这个思路到底怎么做,其实,我觉得自己是清楚的,但是现在想来好多地方,或者说是细节的地方没有相同,这也充分暴露了我思维的漏洞,经常性的理性思维与感性思维“无缝切换”,也就造成了写程序特别不严谨。)
  5. 最后确定的正确的思路是:
    1. 由于需要动态申请,所以需要知道树的最大深度,也就是写个函数,获得树的最大深度,这样二位数组的行确定了
    2. 下面确定列,也就是知道每层节点的数目,写个函数获取每层节点的数目
    3. 这样每层的节点都确定了,而且申请的具体数组也确定,然后就是层次遍历,相当于顺序遍历,因为使用队列,由于知道每层节点的数目,所以就通过记录的数目,将每层的节点分别赋值到相应的数组的行中。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *columnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 * 
 */

void levelNumbersOfTree(struct TreeNode* root, int *levelCount, int level)
{
    if (!root)
        return;
    levelCount[level]++;
    levelNumbersOfTree(root->left, levelCount, level+1);
    levelNumbersOfTree(root->right, levelCount, level+1);
}

int levelTraversal(struct TreeNode* root, int **levelNumbers, int n, int **columnSizes)
{
    if (!root) return 0;
    int count = 0;
    int tail = 1;
    n = 65534;
    struct TreeNode **treeArray = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * (n + 1));
    for (int i = 0; i < n+1; i++) treeArray[i] = NULL;
    treeArray[count] = root;
    int k = 0;
    while (treeArray[count]){
        levelNumbers[k] = (int*)malloc(sizeof(int) * (*columnSizes)[k]);
        for (int j = 0; j < (*columnSizes)[k]; j++){
            levelNumbers[k][j] = treeArray[count]->val;
            if (treeArray[count]->left){
                treeArray[tail] = treeArray[count]->left;
                tail = (tail + 1) % (n+1);
            }
           if (treeArray[count]->right){
                treeArray[tail] = treeArray[count]->right;
                tail = (tail + 1) % (n+1);
            }
            treeArray[count] = NULL;
            count = (count + 1) % (n+1);
        }
        k++;
    }
     free(treeArray);
    return tail;
}

int depthOfTree(struct TreeNode* root)
{
    if (root == NULL)
        return 0;

    int dleft = depthOfTree(root->left) + 1;
    int dright = depthOfTree(root->right) + 1;

    return dleft > dright ? dleft : dright;
}


int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
    if (root == NULL) return NULL;
    *returnSize = depthOfTree(root);
    *columnSizes = (int *)malloc(sizeof(int) * (*returnSize));
    int** levelNumbers = (int**)malloc(sizeof(int*) * (*returnSize));
    for (int i = 0; i < *returnSize; i++){
        (*columnSizes)[i] = 0;
    }
    levelNumbersOfTree(root, *columnSizes, 0);

    int length = levelTraversal(root ,levelNumbers, pow(2.0, *returnSize-1), columnSizes);

    return levelNumbers;
}  

172. Factorial Trailing Zeroes

Given an integer n, return the number of trailing zeroes in n!.

Note: Your solution should be in logarithmic time complexity.

这个题涉及到一个定理

The number of trailing zeros in the decimal representation of n!, the factorial of a non-negative integer n, is simply the multiplicity of the prime factor 5 in n!. This can be determined with this special case of de Polignac’s formula
这里写图片描述

所以根据这个公式很容易写出代码,但是也涉及到一些技巧的问题。
这是初稿:

int trailingZeroes(int n) {
    int ncount = 0;
    for (int i = 1; ; i++){
        long tmp = pow(5, i);
        if (tmp > n)
            break;
        ncount += n/tmp;
    }
    return ncount;
}

次稿

int trailingZeroes(int n) {
    int ncount = 0;
    for (int i = 1; n > 0; i++){
        ncount += n/5;
        n /= 5;
    }
    return ncount;
}

再变

int trailingZeroes(int n) {
    int ncount = 0;
    while (n){
        ncount += n/5;
        n /= 5;
    }
    return ncount;
}

递归的方式

int trailingZeroes(int n) {
    if (n == 0)
    return 0;
return n/5 + trailingZeroes(n/5);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值