前言:笔者转专业学生在美国读研一,平时学习算法主要是通过leetcode,公开课,google等方式。
这次找实习做国内这些笔试的算法编程题,确实发现和平时写的leetcode不一样。有三点要注意
1.要注意输入输出的格式 国内的编程题是纯白板,之前字节跳动是我的第一场笔试,完全没经验,用了很长时间才弄懂国内的平台是怎么处理输入输出的。所以字节笔试直接凉凉,5道才ac一道。
2.leetcode上很多算法的实现的容器大多都是数组这样的容器,有时候不需要你去考虑怎么存储。但是国内的场景编程算法需要你自己考虑如何存储数据。
3.还是要多练习,多亲自去写code。有时候感觉自己好像懂了,实际上代码写出来还是有bug(其实你只懂了八九成)。
然后阿里第一场笔试的时间点上我正在经历部门的二面,所以就没参加上,打算参加27号那场(时间合适)。看了下第一场的题目,感觉还是有难度的,题目的难度大概在leetcode medium和hard之间。
题意
首先定义上升字符串,s[i]≥s[i−1],比如aaa,abc是,acb不是
给n个上升字符串,选择任意个拼起来,问能拼出来的最长上升字符串长度
样例输入
4
aaa
bcd
bcdef
zzz
样例输出
11
解释:最长字符串是aaabcdefzzz,长度为11
这道题类似leetcode上permutation,subset那种题(DFS深搜+backtrack回溯)实际上最简单的思考也是暴力搜索,考虑的是把每个字符串拼接,存储一个全局变量去保存当前传入字符串的长度最大值。
dfs+backtrack图例
代码如下:
public class Main {
/**
* 动态保存全部最大值
*/
private static int maxLength = 0;
/**
* 旋律,由输入满足每个字符串递增
*/
private static List<String> melodies;
public Main(List<String> melodies){
Collections.sort(melodies);
this.melodies=melodies;
}
public static void main(String[]args){
Scanner sc = new Scanner(System.in);
melodies = new ArrayList<>();
int n= sc.nextInt();
for(int i=0;i<=4;i++){
String input = sc.nextLine();
if(input.length()==0){
continue;
}
melodies.add(input);
}
Main mainSolver = new Main(melodies);
helper("",0);
System.out.println(maxLength);
}
/**
*
* @param s 传入的当前字符串String
* @param n 每次搜索开始位置
*/
private static void helper(String s,int n){
if(n>=melodies.size())return ;
for(int i=n;i<melodies.size();i++){
String current = melodies.get(i);
if(s==""||current.charAt(0)>=s.charAt(s.length()-1)) {
String temp=s;
s += current;
maxLength = Math.max(maxLength,s.length());
helper(s, i + 1);
s = temp;
}
}
}
}
一定要注意在每个for循环里的最后要进行回溯!在本题中可以先用一个temp字符串保存,最后再赋值给s。
不懂回溯的同学,或者很久没看回溯的同学建议先复习一下相应知识点。
时间复杂度:2^N 空间复杂度:搜索树的深度
PS:今天在听CS188AI这门课的CSP的时候,发现老师讲到了backtracking!
后记:其实写这篇文章的时候,阿里部门二面过了,现在只剩笔试和总监面HR面。我和二面boss聊的时候还问笔试一道都ac不出来怎么办。boss说哈哈哈那你在之后的面试要解释一下为什么了,总之去写,笔试也只是一个参考而已,不是硬性指标。
anyway,希望笔试顺利!笔试要是不顺利也希望闲鱼网开一面让我过鸭~ 疫情之下的北美学生找实习太不容易了 回国的机票再不订就买不起了咳咳,可是阿里的offer还没拿到呢,又不敢订机票。
笔者水平有限,文章难免有疏忽或者错误,还请读者指正。有什么想法请大家互相交流学习~