百度策略岗(C++)面试复盘

  1. 给出N个数,如何找出top k个值:随机快排、堆。

  2. C++ 五大内存分区:堆、栈、全局/静态存储区、字符串常量区和代码区。

  3. 随机打乱N个数,使得每个数在每个位置的概率为 1 N \frac{1}{N} N1。 完美洗牌问题:

    # 完美洗牌问题
    # 令N个数存在一个列表/数组中
    for i in 1~N:
        num = random(1, i)  # 生成1~i的之间的随机数
        swap(num, i)  # 交换下标为i和小标为num的数的位置
    

    证明:

    利用数学归纳法

    1. N = 1 时,即当前仅有一个数,此数在每个位置的概率为1(此时仅有一个位置),满足概率 1 N \frac{1}{N} N1

    2. 证明,若当 N = K 时,每个数在满足各个位置的概率为 1 N \frac{1}{N} N1,那么就有 N = K + 1 时,每个数在各个位置的概率为 1 K + 1 \frac{1}{K+1} K+11(= 1 N \frac{1}{N} N1)。

      1. 对于第 K + 1 个数,易知其在 1~K+1 中任意位置的概率为 1 K + 1 \frac{1}{K+1} K+11

      2. 对于前 K 个数,已知有一数 a (1<=a<=K) 其在 1~K 中任意位置的概率为 1 K \frac{1}{K} K1 ,现在插入第 K + 1 个数,其不与 a 交换的概率为 1 − 1 K + 1 1 - \frac{1}{K+1} 1K+11,所以插入新数字后有,数 a 出现在任意位置的概率为:
        1 K ∗ ( 1 − 1 K + 1 ) = 1 K + 1 \frac{1}{K}*(1-\frac{1}{K+1}) = \frac{1}{K+1} K1(1K+11)=K+11

  4. 给定1、2、5、10、20、50面额的纸币,给定一个数N,如何用最少面额纸币凑N。

    错误解法:贪心

    正确解法:动态规划

    写代码。

    # 凑多少元
    N = 24
    # 新增12元纸币,这也是为什么不能用贪心的原因
    money = [1, 2, 5, 10, 12, 20, 50]  
    
    big_int = 99999 # 自定义一个较大的数
    t = [big_int] * (N + 1)
    def solve():
        for i in range(1, N+1):
            if i in money:   # 一张纸币能付清的情况
                t[i] = 1
            else:
                tmin = big_int   
                for j in money:
                    if j >= i:
                        continue
                    z = t[i - j]   # 找最少的纸币数
                    if z < tmin:
                        tmin = z
                t[i] = tmin + 1
    
    solve()
    print t[N]
    
  5. 现有一日志,每个记录中有IP,统计该日志(大文件)中出现次数最多的top K个IP。

    我的解法:时间复杂度O(nlogn)

    1. 需要统计 <IP – 个数>,这样的键值对,采用字典数据结构。

    2. 考虑到IP地址很多(ipv4),又是字符串,作为键将占用大量内存,需用hash方法将IP地址转为一个数。

    3. 考虑到文件很大,无法一次性存入全部IP(就算将其转为int32的一个数),于是需要将文件进行切分,具体方法为,对IP进行映射,例如取模N,然后将该数据写入对应文件。此做法保证相同IP映射到同一文件。

    4. 分别遍历各个文件,统计IP频度,取top K条记录,利用快排、堆等算法即可。

    5. 此时获取到NK个键值对,再利用快排、堆等算法取top K条记录即可。

    6. 将int32计算回ip地址。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值