关于算法笔试的几个套路,一点就透
以下文章来源于labuladong ,作者labuladong
我知道各位是被标题吸引进来的,那就不废话,先说几个算法笔试的硬核套路,再说说语言选择和做题复习的策略。
避实就虚
大家也知道,大部分笔试题目都需要你自己来处理输入数据,然后让程序打印输出。判题的底层原理是,把你程序的输出用 Linux 重定向符> 写到文件里面,然后比较你的输出和正确答案是否相同。
那么有的问题难点就变得形同虚设,我们可以偷工减料,举个简化的例子,假设题目说给你输入一串用空格分隔的字符,告诉你这代表一个单链表,请你把这个单链表翻转,并且强调,一定要把输入的数字转化成单链表之后再翻转哦!
那你怎么做?真就自己定义一个 ListNode 单链表节点类,然后再写代码把输入转化成一个单链表,然后再用让人头晕的指针操作去老老实实翻转单链表?
搞清楚我们是来 AC 题目的,不是来学习算法思维的。正确的做法是直接把输入存到数组里,然后用 双指针技巧 几行代码给它翻转了,然后打印出来完事儿。
我就见过不少这种题目,比如题目说输入的是一个单链表,让我分组翻转链表,而且还特别强调要用递归实现,就是我们旧文 K 个一组翻转链表 的算法。嗯,如果用数组进行翻转,两分钟就写出来了,嘿嘿。
还有我们前文 扁平化嵌套列表 讲到的题目,思路很巧妙,但是在笔试中遇到时,输入是一个形如 [1,[4,[6]]] 的字符串,那直接用正则表达式把数字抽出来,就是一个扁平化的列表了……
巧用随机数
再说一个鸡贼的技巧,注意那些输出为「二值」的题目,二值就是类似布尔值,或者 0 和 1 这种组合有限的。
比如说很多题目都类似这样,巴拉巴拉给你说一堆条件,然后问你输入的数据能不能达成这些条件,如果能的话请输出 YES,不能的话输出NO。
如果你会做当然好,如果不会做怎么办?
首先这样提交一下:
public class Main {public static void main(String[] args) {System.out.println("YES");}
}
看下 case 通过率,假设是 60%,那么说明结果为 YES 有 60% 的概率,所以可以这样写代码:
public class Main {public static void main(String[] args) {// 60% 的概率输出 YES,40% 的概率输出 NOSystem.out.println((new Random().nextInt() % 100) < 60 ? "YES" : "NO");}
}
多提交几次,整出个 80% 以上的 case 通过不是问题。
嘿嘿,labuladong 说了,这题你可以不会,但是一定要在力所能及的范围内做到极致!
概率大师
说一个场景,如果笔试出现那种恶心人的单选,四个选项全都没见过,然后你蒙了一个 C。
假设,过了一会你突然灵光一闪,唤起一些零碎的记忆,确定 B 选项是错的,那么,这时候你该怎么做?
重新在 A 和 D 中间蒙一个啊哥哥!不重新蒙,正确的概率是 1/4,重新蒙,正确的概率是 3/8,白捡的概率都不要么?
是不是觉得不可思议?是不是觉得我在胡扯?
这样,假设一道选择题有 100 个选项,你随便蒙一个,正确率为 1%,错误率为 99%。
假设现在 labuladong 显灵,帮你在剩下的 99 个选项中排除了 98 个错误选项,只剩下一个选项,然后问你,你继续坚持原来的选择,还是换成帮你排除剩下的那个选项?
换啊!换了之后正确概率是 1 - 1% = 99% 啊!
那如果 labuladong 只帮你排除了 90 个错误选项,剩下 9 个选项,那你要不要换成这 9 个选项中的某一个?
换啊!换了之后正确概率是 (1 - 1%) / 9 = 11% 啊!
那回过来看,四个选项,你开始蒙了一个,后来灵光一闪在剩下三个选项中排除了一个错误答案,那你换不换?
换啊!换了之后正确概率是 (1 - 1/4) / 2 = 3/8 啊!
其实这就是典型的「三门问题」。
编程语言的选择
仅从做算法题的角度来说,我个人比较建议使用 Java 作为笔试的编程语言。因为 JetBrain 家的 IntelliJ 实在是太香了,相比其他语言的编辑器,不仅有 psvm 和 sout 这样的命令缩写(你要是还不知道命令缩写,赶紧面壁去),而且可以帮你检查出很多笔误,比如说 while 循环里面忘记递增变量,或者 return 语句错写到循环里这种由于疏忽所导致的问题。
C++ 也还行,但是我觉得没有 Java 好用。我印象中 C++ 连个分割字符串的 split 函数都没有,光这点我就不想用 C++ 了……
还有一点,C++ 代码对时间的限制苛刻,别的语言时间限制 4000ms,C++ 限制 2000ms,我觉得挺吃亏的。怪不得看别人用 C++ 写算法,为了提高速度,都不用标准库的 vector 容器,非要用原始的 int[] 数组,我看着都头疼。
Python 的话我刷题用的比较少,因为我不太喜欢用动态语言,不好调试。不过这个语言的奇技淫巧太多,如果你深谙 Python 的套路,可以在某些时候投机取巧。比如说我们前文写到的 表达式求值算法 是一个困难级别的算法,但如果用 Python 内置的 exec 函数,直接就能算出答案。
这个在笔试里肯定是很占便宜的,因为之前说了,我们要的是结果,没人在乎你是怎么得到结果的。
解法代码分层
代码分层应该算是一种比较好的习惯,可以增加写代码的速度和降低调试的难度。
简单说就是,不要把所有代码都写在 main 函数里面,我一直使用的套路是,main 函数负责接收数据,加一个 solution 函数负责统一处理数据和输出答案,然后再用诸如 backtrack 这样一个函数处理具体的算法逻辑。
举个例子,比如说一道题,我决定用带备忘录的动态规划求解,代码的大致结构是这样:
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 主要负责接收数据int N = scanner.nextInt();int[][] orders = new int[N][2];for (int i = 0; i < N; i++) {orders[i][0] = scanner.nextInt();orders[i][1] = scanner.nextInt();}// 委托 solution 进行求解solution(orders);}static void solution(int[][] orders) {// 排除一些基本的边界情况if (orders.length == 0) {System.out.println("None");return;}// 委托 dp 函数执行具体的算法逻辑int res = dp(orders, 0);// 负责输出结果System.out.println(res);}// 备忘录static HashMap<String, Integer> memo = new HashMap<>();static int dp(int[][] orders, int start) {// 具体的算法逻辑}
}
你看这样分层是不是很清楚,每个函数都有自己主要负责的任务,如果哪里出了问题,你也容易 debug。
倒不是说要把代码写得多规范,至于 private 这种约束免了也无妨,变量用拼音命名也 OK,关键是别把代码直接全写到 main 函数里面,真的乱,不出错也罢,一旦出错,估计要花一番功夫调试了,找不到问题乱了阵脚,那是要尽量避免的。
考前复习策略
考前就别和某一道算法题死磕了,不划算。
应该尽可能多的看各种各样的题目,思考五分钟,想不出来解法的话直接看别人的答案。看懂思路就行了,甚至自己写一遍都没必要,因为比较浪费时间。
笔试的时候最怕的是没思路,所以把各种题型都过目一下,起码心里不会慌,只要有思路,平均一道题二三十分钟搞定还是不难的。
前面不是说了么,没有什么问题是暴力穷举解决不了的,直接用 回溯算法套路框架 硬上,大不了加个备忘录,不就成 动态规划套路框架 了么,再大不了这题我不做了么,暴力过上 60% 的 case 也挺 OK 的。
别的不多说了,套路这个东西,说来简单,一点就透,但问题是不点就不透。本文我简单介绍了几个笔试算法的技巧,各位好好品味~
算法真的没那么难,这一切只是手段而已,过算法笔试拿 offer 才是目的。为了达到目的,套路是必须的,《labuladong的算法小抄》将会为你提供这方面的帮助,可以少走很多弯路!
▊《labuladong的算法小抄》
付东来(@labuladong) 著
- GitHub 68.8k star的硬核算法教程
- labuladong带你挑战力扣算法题
- 挑战BAT等大厂Offer
本书专攻算法刷题,训练算法思维,应对算法笔试。注重用套路和框架思维解决问题,以不变应万变。
关于算法笔试的几个套路,一点就透相关推荐
- labuladong 的算法小抄_关于算法笔试的几个套路,一点就透
以下文章来源于labuladong ,作者labuladong 我知道各位是被标题吸引进来的,那就不废话,先说几个算法笔试的硬核套路,再说说语言选择和做题复习的策略. 避实就虚 大家也知道,大部分笔试 ...
- 2020年腾讯实习生算法笔试题目(感触良多)
2020年腾讯实习生算法笔试题目 题目描述 代码示例 题目描述 代码示例 题目描述 代码示例 快速幂求解代码示例 题目描述 代码示例 题目描述 代码示例 参加了腾讯20年的实习生笔试,本来都不打算 ...
- 算法笔试模拟题精解之“Tom 爱吃巧克力”
算法笔试模拟题精解之"Tom 爱吃巧克力" 本人C++菜鸟一枚,题目可以做出结果,但是相信各位大佬们会有更好的解法,如果有错误,欢迎在评论区指出,一起学习 **题目:**Tom 非 ...
- 今日算法笔试练习【5】(08-06)(历年笔试题)
一 .爱奇艺2019秋招算法方向笔试题(A) 1. 使用堆排序方法排序(45,78,57,25,41,89),初始堆为( ) 首先根据现有的序列进行二叉树的构建得到: 然后将这棵二叉树转化为 ...
- 快速开平方根倒数算法(Fast inverse square root)的一点探究
文章目录 一.写在前面 1. 提示 2. 背景与前情 二.正文 1. 需求分析 2. 必备工具之IEEE-754浮点数表示方法 3. 同一储存单元32bits的两种不同意义 4. 公式推导 4. 本文 ...
- c语言插入排序_还有这种操作?C语言插入排序算法,一点就透
插入排序算法是所有排序方法中最简单的一种算法,其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据. 更多C/C++资料群文件:569268376 直接 ...
- 快手2018年招聘算法笔试
9月之前的题目 九宫格重排: 题目:https://www.cnblogs.com/ranjiewen/p/8998166.html 解答:https://www.cnblogs.com/lifexy ...
- 快手2019秋季校园招聘算法笔试A卷编程题 - 题解
快手算法笔试题,两个动态规划,一个签到题.数据太恶心了,魔法深渊那题,没给模,后来是我自己根据结果猜出来的,模是100000000310000000031000000003,居然还不是常规的10000 ...
- 快手2019秋季校园招聘算法笔试B卷编程题 - 题解
快手算法笔试题,一个签到题,一个动态规划,一个二分答案.其中二分答案有个数据有问题. 题目链接:点这儿. 字符串排序 题目 月神拿到一个新的数据集,其中每个样本都是一个字符串(长度小于100),样本的 ...
最新文章
- 设置placeholder无效解决办法
- html二级导航栏随一级居中,html – 1.在css中链接不起作用2.如何垂直居中导航栏并在每个导航栏上添加填充...
- 【Python】可视化分类型变量,我一般使用这6种图形。
- Spring IoC 源码系列(三)Spring 事件发布机制原理分析
- CRMEBv3.0版本更新了什么?
- C# 计算时间差 用timespan函数
- 如何为物联网选择微控制器?
- window safari 怎么进入响应式_Web前端新手怎么入门 如何用CSS做响应式布局
- 从入门到入土:基于C语言实现并发Web服务器|父进程子进程|代码展示
- mac linux win三系统安装教程,【教程】Windows、Linux、MacOS安装adb工具的方法
- java 利用Future异步获取多线程任务结果
- 基于DEAP库的python进化算法-2.进化算法各元素的DEAP实现
- ckplayer播放线上视频问题
- 新颖的自我介绍_新颖一分钟自我介绍4篇
- Stata-交乘项专题: 主效应项可以忽略吗?
- 全渠道会员通-天猫会员通2: 常见问题
- 最大帧长和最小帧长详解
- CSR8675学习笔记:USB HID通信
- 【IDEA】- IDEA导入 mysql驱动包的时候 编译时可以找到驱动包 , 但是运行时无法找到
- windows10简单试用多图,连薛定谔的猫都杀死了