書:cracking the coding interview 豆瓣 亞馬遜
網站:careercup
代碼風格
代碼塊可分為三大塊:異常處理(空串和邊界處理),主體,返回值
代碼風格(可參考Google的編程語言規范)
- 變量名的命名(有意義的變量名)
- 縮進(語句塊)
- 空格(運算符兩邊)
- 代碼可讀性(即使if語句只有一句也要加花括號)
《代碼大全》中給出的參考
基本代碼素養
- 關于空格
for,if,else,while等記得加空格符
用空行把大塊代碼分成邏輯上的“段落” - 關于括號
c指針中的指針符靠近類型名,如寫成int* p,而不寫成int *p
一個函數只專注做一件事 - 關于命名
駝峰寫法
實戰算法策略
- 總結歸類相似題目
- 找出適合同一類題目的模板程序
- 對基礎題熟練掌握
再看一道簡單題
Memmove
void *memmove(void *dest, const void *src, size_t n)
{
// implementation here
}
陷阱
- 內存重疊的處理
- 臨時變量太多或者沒有安全釋放
- 沒有測試內存越界
- 指針操作不熟悉
正確寫法
void *memmove(void *dest, const void *src, size_t n)
{
char *p1 = dest;
const char *p2 = src;
if (p2 < p1) {
p2 += n;
p1 += n;
while (n-- != 0)
*--p1 = *--p2;
} else {
while (n-- != 0)
*p1++ = *p2++;
}
return p1;
}
排列組合模板
Subsets
{1,2,3}
{{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}}
轉化為程序問題
Subsets
void subsets(int[] num) {
ArrayList<Integer> path = new ArrayList<Integer>();
Arrays.sort(num);
subsetsHelper(path, num, 0);
}
void subsetsHelper(ArrayList<Integer> path, int[] num, int pos) {
outputToResult(path);
for (int i = pos; i < num.length; i++) {
path.add(num[i]);
subsetsHelper(path, num, i + 1);
path.remove(path.size() - 1);
}
}
Subsets-Sample
對遞歸圖的理解
Unique Subsets
{1,2,2}
{{},{1},{2},{1,2},{2,2},{1,2,2}}
Unique Subsets
- 與Subsets有關,先背下Subsets的模板
- 既然要求Unique的,就想辦法排除掉重復的。
- 思考哪些情況會重復?如{1,2(1),2(2),2(3)},規定{1,2(1)}和{1,2(2)}重復,{1,2(1),2(2)}和{1,2(2),2(3)}重復。觀察規律。
- 得出規律:我們只關心取多少個2,不關心取哪幾個。
- 規定必須從第一個2開始連續取(作為重復集合中的代表),如必須是{1,2(1)}不能是{1,2(2)}
- 將這個邏輯轉換為程序語言去判斷
Unique Permutations
[1,2,2]
[1,2,2],[2,1,2],[2,2,1]
排列組合模板總結
- 使用范圍
幾乎所有的搜索問題 - 根據具體題目要求進行改動
什么時候輸出
哪些情況需要跳過
使用該模板的題目
- Combination Sum
- Letter Combination of a Phone Number
- Palindrome Partitioning
- Restore IP Address