9.1 深信服笔试

算法工程师岗位,感觉难度在最近做过的其它笔试中算是比较难的一次了。以下代码均为全A通过,可供参考。
第一题:日志分析
一组攻击先后包含 s w r。现有 T 份日志,每份是一个小写字母字符串,需要从每份日志里,统计有多少种可能的潜在攻击。
输入:正整数 T,紧接着是 T 行日志
输出:T 行,每个日志的潜在攻击数。需要对 1e9+7 取模

解法:这题相当于查找字符串中有多少个 "swr" 子序列。用动态规划比较高效,否则有些大测试点估计过不了
考虑如下三个动态规划函数:
  • dp_s。其中 dp_s[i] 代表字符串的前 i 个字符,有多少个子序列 "s"。
  • dp_sw。其中 dp_sw[i] 代表字符串的前 i 个字符,有多少个子序列 "sw"。
  • dp_swr。其中 dp_swr[i] 代表字符串的前 i 个字符,有多少个子序列 "swr"。
状态转移,需要看字符串的第 i 位是什么。比如是 'r',那么它可以额外提供的 "swr" 子序列数量即为 dp_sw[i]。其余同理,因此状态转移函数总结如下:
  • 如果字符串的第 i 位是 's',则 dp_s[i] = dp_s[i - 1] + 1,否则 dp_s[i] = dp_s[i - 1]
  • 如果字符串的第 i 位是 'w',则 dp_sw[i] = dp_sw[i - 1] + dp_s[i],否则 dp_sw[i] = dp_sw[i - 1]
  • 如果字符串的第 i 位是 'r',则 dp_swr[i] = dp_swr[i - 1] + dp_sw[i],否则 dp_swr[i] = dp_swr[i - 1]
注意到,每个函数只有最后一个值会被用到,因此可以用滚动数组节省空间
我只用了 s w r 三个变量表示循环中的三个函数值。最终输出 dp_swr[n] % (1e9+7) 的值即可。
T = int(input())
for _ in range(T):
    info = input()
    s = w = r = 0
    for i in range(len(info)):
        if info[i] == 's':
            s += 1   # 遍历到第i位时,s表示 dp_s[i]的值,下同
        elif info[i] == 'w':
            w += s
        elif info[i] == 'r':
            r += w
    print(int(r % (1e9+7)))
第二题:深信服旅游
有 T 组测试数据。每组包含正整数 n,表示员工数。之后是 n 行,每行两个正整数a, b,表示一位员工方便旅游的时间段为 [a, b]。问最多可以同时让多少位员工觉得方便。
输入:正整数 T。之后 T 组数据,每组先输入正整数 n;然后是 n 行,每行两个正整数
输出:T行,每组测试数据的结果
备注:O(n^2)的算法可得一半分,O(nlogn)的算法可得满分

解法:贪心算法
对于每组数据,分别用数组A, B记下来所有的开始时间和所有的结束时间,并不需要考虑它们来自于哪位员工。将它们升序排列。
为什么不需要考虑它们来自哪个员工呢?
因为我们只关注每个区间的进入退出。比如两个区间 (1,4)+(2,3),实际上和 (1,3)+(2,4) 是没有区别的。
我们要做的,是给定这些区间的首尾值,判断最多有多少个区间重合。
遍历数组A,每次找到 A[i],相当于有一个区间开始。我们还要查看这时有多少区间已经结束。因此需要在数组B中维护一个动态指针p(p表示当前有多少个区间已经结束)。如果当前p指向的结束时间小于 A[i],说明当前的区间已经结束,需要不断将p右移。操作完成后,p 和 i 的下标差加1即为当前区间的重合数
最后,每步中找到的区间重合数去一个最大值即为所求。
T = int(input())
for _ in range(T):   #  T组测试数据
    n = int(input())
    A, B = [], []
    for __ in range(n):     # 每组数据n个员工
        a, b = [int(x) for x in input().split()]
        A.append(a)
        B.append(b)
    A.sort()
    B.sort()
    p = ans = 0
    for i in range(n):
        while p < n and A[i] > B[p]:
            p += 1
        ans = max(ans, i - p + 1)
    print(ans)
第三题:五进制
设定一种五进制,其中 o, y, e, a, s 分别代表 0, 1, 2, 3, 4。例如五进制 ya 代表十进制 8。
有 T 组测试数据。每组包含一个数字,或字母oyeas组成的字符串。实现进制的相互转换,并输出每个测试数据的转换结果。
输入:正整数 T。之后 T 行,每行一个【五进制字母串】或【十进制数】
输出: T 行,给定测试如果是五进制,则输出十进制数;给定测试如果是十进制,则输出五进制字符串

压轴题反而是最简单的,跟二进制转化没啥区别。
十进制转五进制,每次对5取模,得到最低位,然后将数字除以5,直到数字变为零;
五进制转十进制,遍历字符串。长度为 n 的字符串,第 i 位是x,则它的贡献为 x * 5 ^ (n - i - 1)。循环求和即可
import math
T = int(input())
for _ in range(T):
    ipt = input()
    if ipt.isdigit():
        if ipt == '0':
            print('o')
            continue
        ans = ''
        ipt = int(ipt)
        while ipt > 0:
            ans = 'oyeas'[ipt % 5] + ans
            ipt //= 5
        print(ans)
    else:
        ans = 0
        for i in range(len(ipt)):
            ans += 'oyeas'.index(ipt[i]) * math.pow(5, len(ipt) - i - 1)
        print(int(ans))
可能有些地方写得不是很明白,有问题欢迎留言讨论,一起进步!



#深信服##深信服笔试题#
全部评论
题目一样,是算法卷A吧,主要小题不好做
1
送花
回复
分享
发布于 2022-09-01 21:40 广东
太强了,只a出来了第三题
点赞
送花
回复
分享
发布于 2022-09-01 22:05 安徽
秋招专场
校招火热招聘中
官网直投
我咋觉得挺简单的。。。第一题前后缀和,第二题差分数组,第三题模拟白给。小题还有点难度
点赞
送花
回复
分享
发布于 2022-09-01 22:07 江苏
我的python语言不过关,好多系统自带的方法我都不知道,只能现编
点赞
送花
回复
分享
发布于 2022-09-01 22:46 北京
我傻了,原来第二题这么简单就能解决 当时用优先队列a的 (PS:没给用java语言。差点死了(指用cpp头文件都忘记咋写了))
点赞
送花
回复
分享
发布于 2022-09-02 16:08 广东
题解太清晰了!bd
点赞
送花
回复
分享
发布于 2022-09-03 14:24 内蒙古
第2题,深信服旅游那个,当时自己是觉得以为是合并区间,就想到力扣那个戳爆气球那个题,这样写的,但是不正确,但是一直没想通错哪了,大佬们可帮忙看下么? if __name__ == '__main__&(31187)#39;:     T = int(input())     while T:         N = int(input())         times = []         for i in range(N):             time = list(map(int, input().split(" ")))             times.append(time)         times.sort(key=lambda x: x[1])         needs = [times[0]]         ans, cnt = 1, 1         for i in range(1, len(times)):             if times[i][0] > needs[-1][1]:                 needs.append(times[i])                 cnt = 1             else:                 needs[-1][0] = max(needs[-1][0], times[i][0])                 needs[-1][1] = min(needs[-1][1], times[i][1])                 cnt += 1             ans = max(ans, cnt)         print(ans)         T -= 1
点赞
送花
回复
分享
发布于 2022-09-04 16:50 陕西
第二题为什么p 和 i 的下标差加1即为当前区间的重合数?
点赞
送花
回复
分享
发布于 2022-09-16 18:00 广东
安排面试了吗兄弟
点赞
送花
回复
分享
发布于 2022-10-11 13:54 黑龙江

相关推荐

头像
不愿透露姓名的神秘牛友
05-21 22:07
bigo 产品经理 18*16 硕士211
点赞 评论 收藏
转发
#店小秘#一面(60min)1、arraylist和linkedlist的底层实现?&nbsp;两者适用的场景?2、redis的数据类型3、redis常用的是什么数据结构?&nbsp;使用的场景4、redis是单线程还是多线程?&nbsp;为什么要这样设置5、数组和链表的区别,在内存分配这块有什么区别6、栈和堆的区别?7、MySQL有怎么优化过吗8、事务的隔离级别9、了解过索引吗?优点和缺点10、聚簇索引和非聚簇索引的区别?11、RabbitMQ如何避免重复消费(mq经典题)12、假如反馈线上系统有卡顿,如何排查,从哪些方面13、为什么要进行分库分表14、如果sql语句执行慢,如何定位走哪个索引15、拷打项目,具体问项目中的优化、实现场景、为什么这么选择、有没有其他解决方案二面(40min)1、从上一段实习学到了什么,有什么收获2、平时如何学习3、了解synchronized和volatile关键字吗,有什么区别4、synchronized可以怎么来使用(我回答的不太好)5、RabbitMQ消失丢失的场景,如何防止丢失6、了解分布式锁吗(这个也是有点弱)7、redis分布式锁的实现方式8、给一个数据量很大表加字段或者加索引如何加(1、可以直接创新表加,加完复制数据过来,可能会丢失&nbsp;2、可以从库加字段操作,然后主从切换,数据丢失可能性小)9、了解线程池吗?线程池的参数10、谈谈Syschronize锁,锁怎么升级的11、说说你自己有什么优势和劣势12、捞点家常和询问职业规划总结:面的八股算基础,主要是对于项目要熟悉,对项目问的比较深且会扩展出来询问(本人较菜)
查看27道真题和解析
点赞 评论 收藏
转发
4.27深圳店小秘网络科技有限公司Java开发工程师全程线下笔试40分钟基础知识+单例+sql+创建10个线程抢票比较简单一面60分钟说一下arrylist实现和扩容机制,linkedlist和arrylist的区别,了解多线程吗,讲一下syschronized,锁升级过程说一下,线程池呢,spring的事务传播机制,mysql的事务呢,具体讲一下,如何解决脏读不可重复读和幻读的,你用的是mysql5还是8,两个版本具体有哪些区别呢,索引失效的场景,聚簇索引和非聚簇索引的区别,b+树和b树的区别,页分裂,用过redis吗说一下你常用的数据结构及如何实现的,mq的使用场景,如何保证消息不丢失,讲一下你的实习项目吧,讲下整个业务流程,你负责的部分,你是怎么解决问题的。二面70分钟(技术+hr)为什么选择学习Java,讲一下hashmap,零拷贝是怎么实现的,说一下数据库的mvcc如何实现的,枚举可以被反射破坏吗,为什么不能,讲一下aqs怎么实现的,为什么从尾节点遍历,如何唤醒挂起线程的,了解中断吗,有看过数据存储方面的书吗,redis怎么保证原子性,分布式锁了解吗,redis挂掉了怎么办,你刚才说了红锁,红锁为什么是超过半数,这个半数怎么来的,主从跟多主都有什么优缺点,平时怎么学习的,你在做项目的时候有遇到分歧吗,如何解决,假如要年会了,领导让你组织组内出一个节目,你的计划是什么,如果没人配合怎么处理,父母对你未来工作有什么看法吗,为什么来深圳,还有别的offer吗。
查看4道真题和解析
点赞 评论 收藏
转发
27 74 评论
分享
牛客网
牛客企业服务