[读书笔记]编程之美(二)

本文是《编程之美》读书笔记的第二部分,涵盖了多个编程问题的解决方案,包括求二进制数中1的个数、阶乘末尾0的数量、寻找发帖“水王”、数组中1的个数、寻找最大的K个数、精确表达浮点数、最大公约数问题、找符合条件的整数、斐波那契数列、寻找数组中的最大值和最小值、最近点对、快速寻找和为特定值的两个数、子数组的最大乘积、子数组之和的最大值等。文章通过算法解析和实例探讨了这些问题的高效解法。
摘要由CSDN通过智能技术生成

[读书笔记]编程之美(二)

2.1求二进制数中1的个数

  • 问题:对于一个字节(8bit)的无符号整形变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高。
  • 思路:
n = n & (n-1);

当然因为只有8bit所以直接定义一个256的int数组表,直接返回结果,时间复杂度是O(1)。

2.2不要被阶乘吓到

  • 问题:1.给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3628800,N!的末尾有两个0。
    2.求N!的二进制表示中最低位1的位置。
  • 思路:从“那些数相乘能得到10”这个角度来考虑,对N!进行质因数分解,N!=(2X方)(3Y)(5Z)…所以res = min(X,Z)。
    问题1的解法一
for(int i = 1; i <= N; i++)
{
    j = i;
    while(j % 5 == 0)
    {
        res ++;
        j /= 5;
    }
}

解法二: Z = [N/5] + [N/25] + [N/125] + …

while(N)
{
    res += N/5;
    N /= 5;
}

问题二:等于求N!含有质因数2的个数。即等于N!含有质因数2的个数加一。

while(N)
{
    N = N >>= 1;
    res += N;
}

N!含有质因数2的个数,还等于N减去N的二进制中表示1的数目。

2.3寻找发帖“水王”

  • 问题:传说,Tango有一“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找到这个传说中的Tango水王吗?
  • 思路:如果每次删除两个不同的ID(不管是否包含”水王“的ID),那么,在剩下的ID列表中,”水王“ID出现的次数仍然超过总数的一半。
for(int i = nTimes = 0; i < N; i++)
{
    if(nTimes == 0)
    {
        candidate = ID[i], nTimes = 1;
    }
    else
    {
        if(candidate == ID[i])
            nTimes++;
        else
            nTimes--;
    }
}
return candidate;

2.4 1的数目

  • 问题:1.给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现所有”1“的个数。f(12) = 5。
    2.满足条件“f(N) = N”的最大的N是多少?
  • 思路:假设N=abcde,这里a、b、c、d、e分别是十进制数N的各个数位上的数字。如果要计算百位上出现1的次数,它将会受到三个因素的影响:百位上的数字,百位以下的数字,百位以上的数字。
while(n / iFactor != 0) //这里iFactor可以是0~9任意一个数
{
    iLowerNum = n - (n/iFactor) * iFactor;
    iCurrNum = (n/iFactor) % 10;
    iHigherNum = n / (iFactor * 10);

    switch(iCurrNum)
    {
        case 0:
            iCount += iHigherNum * iFactor;
            break;
        case 1:
            iCount += iHigherNum * iFactor + iLowerNum + 1;
            break;
        default:
            iCount += (iHigherNum + 1) * iFactor;
            break;
    }
    iFactor *= 10;
}

问题二的解法:
容易从上面的式子归纳出: f(10n1)=n10n1 。容易得出 n=10101 时, f(n) 的值大于n。
通过类似数学归纳法的思路来推理这个问题,证明满足条件 f(n)=n 的数存在一个上界。
计算这个最大数n
N=10111=99999999999 ,让n从N往0递减,依次检查是否有 f(n)=n ,第一个满足条件的就是我们要求的整数。得出n = 1 111 111 110 是满足 f(n)=n 的最大整数。

2.5寻找最大的K个数

  • 问题:有很多无序的数,假定他们各不相等,怎么选出其中最大的若干个数呢?
  • 思路:
    1.在数据量不大的情况下,可以选择快排或者堆排序O( N/log2N ),选择排序和交换排序O( NK )。在 K(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值