Code interview:Coding 面試與思考訓練 - 實戰演練 part 2
緣起:Code interview:Coding 面試與思考訓練 - 💻 MF99 coding
題目:
給定一組人的列表,列表當中有記錄著他們每個人的出生以及死亡年份 問題﹔請找出人口數量最多的年份
在上一篇,我們已經列舉出了一組相對看起來客觀且具代表性的實例,接著就是試著在邏輯上找出我們的解答。
數據:
人名 | 出生 | 死亡 |
---|---|---|
A | 1920 | 1980 |
B | 1974 | 1998 |
C | 1933 | 1954 |
D | 1923 | 1999 |
E | 1902 | 1958 |
F | 1901 | 1928 |
G | 1963 | 2009 |
H | 1938 | 1979 |
J | 1949 | 1991 |
K | 1913 | 1959 |
L | 1975 | 2010 |
時間軸參考
3. 暴力破解 (Brute Force)
從時間軸來看,似乎我們要找的就是這些線段裡面重疊最多的年份。
但是如何把幾何問題轉換到代數問題呢?
這時候我們可以先試著暴力破解這個問題~
最直覺(笨)的做法,就是我們一年一年的來看,每一年的人口數。
按照時間順序列出來,然後觀察總體人口的變化。
年份 | 人口 | 年份 | 人口 |
---|---|---|---|
1901 | 1 | 1959 | 4 |
1902 | 2 | 1963 | 5 |
1913 | 3 | 1974 | 6 |
1920 | 4 | 1975 | 7 <- MAX |
1923 | 5 | 1979 | 6 |
1928 | 4 | 1980 | 5 |
1933 | 5 | 1991 | 4 |
1938 | 6 | 1998 | 3 |
1949 | 7 <- MAX | 1999 | 2 |
1954 | 6 | 2009 | 1 |
1958 | 5 | 2010 | 0 |
所以初步列出來之後,我們就有一個基於這個暴力破解法的演算法
population: int = 0 for(i from startYear to lastYear){ if (i has someone birth) population++ if (i has someone die) population-- if(population > MAX_POPULATION) MAX_POPULATION = population } return (the years that population matches MAX_POPULATION)
簡單來說,就是每一年去看當年的人口數,並且從中找出最大值。
最後再針對這個最大值,反查出這是在哪一個年份發生的。
4. 優化 (Optimize)
接下來就是再次檢視整個暴力破解的過程,我們可以發現幾點:
- 其實不需要每一年都看,因為人口的變化只會出現在有人出生或是死亡的年份。
- 由於我們關注的只有人口最大值,人口最大值基本上只會出現在有人出生的年份(因為有人去世的年份,人口只會減少不會變多)
所以,與其計算每一年的人口變化,不如
優化 1
只關注在「有人出生」的那一年的人口數
接著,進一步思考,以下這個問題
人口數的定義是什麼?
透過手動計算,與時間軸的觀察。 可以發現到人口數的定義:
優化 2
P(Y) 表示第Y年的人口數 P(Y) =(比Y早出生的人)-(比Y早去世的人)
透過優化 1+2,看起來我們就有一個可行的優化演算法了
list : List<Human> populationRecord : Map<year, population> // Record population for each year // And also find the MAX_POPULATION for (Human in list){ Y = Human.birth population = (num of birth years < Y) - (num of death years < Y) populationRecord.put( Y, population ) if (population > MAX_POPULATION) MAX_POPULATION = population } maxPopulationYears: List<Year> // Extract the Years that matches MAX_POPULATION for(Years in populationRecord){ if( population == MAX_POPULATION) maxPopulationYears.add(Year) } return maxPopulationYears
下一步就可以準備動手寫 Code 了!
Code interview:Coding 面試與思考訓練 - 實戰演練 part 3 - 💻 MF99 coding
雜記
其實,這篇裡面提到的這兩個步驟,看起來好像很流暢,很順的就可以這樣解出來
但是實際上在實戰中,這兩步驟是最難的,也是花最多時間的。
所以才會需要多一點練習,如何在摸不著頭緒的題目中,先試著用最簡單的暴力破解法來解決(有些題目連暴力破解都還要想一下...)
然後再從暴力破解的過程中找出規律、規則,找出可以用程式寫成邏輯的部分。
所以最好一開始的暴力破解法是用手寫,而不要一開始就試著用程式寫。
另外還有一點很重要的技巧,就是跟 面試官的互動,台灣人常常在解題的過程都是內心戲,毫無動靜的在腦中思考。
當然靜下心思考也是很重要,但是別忘了你現在正在面試! 外國公司常常是在面試的過程中,一方面除了看你有沒有能力解決這些問題之外,另外一方面也是在觀察妳的思考邏輯跟思路方向。 所以練習在思考的過程,同時也能夠用口述的表達自己目前在思考的方向,思考的策略也是很重要。
因為有時候常常題目過於奇耙,或是有時候剛好就是時間不夠無法完整的解決。 但是如果面試官覺得你的思考方向正確,並且思考過程是合乎他們的要求的,在面試分數上基本上也不會太差!(總比過程什麼都不講,面試官也不知道你在想什麼,然後最終題目也沒解出來好太多)