day09之N的階乘N!末尾有多少個0 + 二叉樹的層序遍歷

  • 給定一個整數N,那麼N的階乘N!末尾有多少個0呢?例如:N=10,N!=3 628 800,N!的末尾有兩個0
    思路:看到這題我們直觀的思路就是先求出N!,再判斷N!末尾有多少個0,但是這有個問題,當N 很大的時候,會溢出,所以這種思路只能計算N很小的情況。
int ZeroOfNum(int num)
{
    assert(num > 0);

    int i = 1;
    long long sum = 1;
    for(; i <= num; ++i)
    {
        sum *= i;
    }

    cout << sum <<endl;

    int size = 0;
    while(sum && (sum % 10 == 0) )
    {
        size++;
        sum /= 10;
    }

    return size;
}

思路2:如果N!= K×10^M,且K不能被10整除,那麼N!末尾有M個0。再考慮對N!進行質因數分解,N!=(2^x)×(3^y)×(5^z)…,由於10 = 2×5,所以M只跟X和Z相關,每一對2和5相乘可以得到一個10,於是M = min(X, Z)。不難看出X大於等於Z,因爲能被2整除的數出現的頻率比能被5整除的數高得多,最終問題轉化爲求Z的值-即找出1…N能分解出多少個5

int ZeroOfNum2(int num2)
{
    assert(num2 > 0);

    int size = 0;
    for(int i = 1; i <= num2; ++i)
    {
        int temp = i;
        while(temp %5 == 0)
        {
            size++;
            temp /= 5;
        }
    }
    return size;
}

公式:Z = [N/5] +[N/5^2] +[N/5^3] + …(不用擔心這會是一個無窮的運算,因爲總存在一個K,使得5^K > N,[N/5^K]=0。)

公式中,[N/5]表示不大於N的數中5的倍數貢獻一個5,[N/5^2]表示不大於N的數中5^2的倍數再貢獻一個5

int ZeroOfNum3(int num3)
{
    assert(num3 > 0);
    int ret = 0;   
    while(num3)   
    {  
        ret += num3 / 5;   
        num3 /= 5;  
    }
    return ret;
}
  • 實現一顆二叉樹的層序遍歷。

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
        val(x), left(NULL), right(NULL) {
        }
};


void LevelOrder(TreeNode *root)
{
    if(root == NULL)
        return ;
    queue<TreeNode *>q;

    q.push(root);
    while(!q.empty() )
    {
        TreeNode *temp = q.front();
        if(temp->left)
            q.push(temp->left);
        if(temp->right)
            q.push(temp->right);
        cout << temp->val << " ";
        q.pop();
    }
    cout << endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章