前言:筆者轉專業學生在美國讀研一,平時學習算法主要是通過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還沒拿到呢,又不敢訂機票。
筆者水平有限,文章難免有疏忽或者錯誤,還請讀者指正。有什麼想法請大家互相交流學習~