秋招笔试使用Python编程的注意事项

上研究生这一两年一直在用Python,习惯了Python的库函数。由于Java语法严格又比较复杂,容易扰乱算法思路,并且太久没用以前擅长的C++,最近笔试一直首选Python。Python在笔试编程题中具有简洁易读、易于操作和大量的库支持的优点。然而,需要注意Python的执行效率,否则只要题目卡边界和时间就很难100%AC。根据笔试情况,总结了一些笔试注意事项。

优势

  • 基础类型丰富
    • int 天然支持大整数
    • string 类型支持 slice、反转等,语法灵活
    • dict 可作为哈希
  • 语法简洁,动态类型
    • 定义变量不用指定类型,更关注算法
    • mapzip、列表表达式等减少代码量
    • 支持多返回值
  • 特殊函数
    • eval 表达式求值
    • cache装饰器快速实现记忆化搜索 ,无序额外逻辑

劣势

  • 执行速度慢!!!

  • 不支持排序集合、排序map,其中 OrderedDict 是有序字典,类似于Java的LinkedHashMap

  • CPython解释器限制最大递归深度为1000

笔试问题汇总

  1. for循环超时

    • 去掉if判断:根据条件,改用max、min等函数(希音第一题背包问题)
    • 合并多行语句:例如对于每次结果取模,直接在计算时取模,而不是额外判断或者先更新dp[i]再取模
      点名京东笔试第二题,正常写只能通过96%。
      题意:每次选择数组末尾两个数,进行求和或者乘积,将结果最后一位数字取代后两位数。求n-1次操作后剩下的数0~9分别有多少种可能。
      dp[i][0-9]:第i位出现0-9的方案数
      递推公式:dp[i][v*arr[i+1]%10] += dp[i+1][v], dp[i][(v+arr[i+1])%10] += dp[i+1][v]
    • 2023/9/3 奇安信第二题背包超时(AC80%, 2001ms):尝试各种优化第二层循环仍旧超时,改用Java AC(16ms)。
  2. 使用PriorityQueue、heapq超时
    queue 库有线程同步操作,执行比较慢(参考我的博客第8条分析)。先考虑替换heapq(文远知行第三题通过92%),实在不行换语言吧。
    Java 优先队列,使用Lambda匿名函数,注意返回类型为 int

    PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2)->(o1[1]-o2[1]));
    
  3. RuntimeError: maximum recursion depth exceeded
    参考python递归次数过多,导致报错或者溢出

    import sys                    # 导入sys模块
    sys.setrecursionlimit(10000)  # 将默认的递归深度修改为10000
    

    点名米哈游第二题,考试时改用栈模拟递归调用,也可以用BFS替换DFS

  4. 搜索需要记忆化
    使用cache装饰器

    • 美团第一轮笔试第5题,树形DP:求满足父子乘积为平方数的最大不能连续染色的节点数。
    from functools import cache
    // 加在需要记忆化的函数上,参数务必为可哈希类型
    @cache
    def dfs(u, flag=False, fa=-1):
        pass
    
    • 2023/9/3 奇安信第一题:将数组分为相等的四部分,DFS爆搜+剪枝。不加cache只能AC 80%。
posted @ 2023-08-14 12:45  izcat  阅读(223)  评论(0编辑  收藏  举报