貢獻者: 半條悟-satoru
模擬面試錄影-1 (漢)
模擬面試錄影-2 (漢)
模擬面試錄影(英)
你好,我是今天主持這場面試的人,文遠,那我們就開始面試。
第一題,給予一個內容都是整數integer的vector,以及一個數字以下稱為target,請你印出兩個數字的index,而這兩個數字相加會等於target。
你可以假設在整個vector中只有一組解,印出的index順序不拘,但你不可以使用同個元素兩次。
也就是說,比如我有一個vector內含[2,5,7,16,21,10],如我螢幕上所示,且target = 12,那麼預期得到的結果是[1,2]嗎?
是的沒錯。
再比如說,我有一個vector內含[2,7,7,8,10,19],如我螢幕上所示,且target = 14,那麼預期得到的結果是[1,2]嗎?
是的,這也正確。
感謝,那我首先想到的方法是,以兩個for迴圈,遍歷這個vector,外圈for固定住第1個數,內圈for尋找index在第1個數之後的所有元素,並嘗試找出與他相加等於target的數。在找到配對的時候記錄下兩個for回圈當下的index,立刻return。
(大略說完後,一邊寫扣一邊配合註解並解說)
我完成了,請問有什麼問題嗎?
感覺相當不錯,那你可以分析一下當前這個解法的時間複雜度嗎?
第一個迴圈從第0個到n-1,而第二個迴圈會做n-1次、n-2次、n-3次…所以這個方法的時間複雜度為
那我們是否有方法節省更多時間,讓資料不需要讀那麼多次呢?
或許可以用一個map並遍歷一次vector。
每次看到元素的當下先以「target減當前元素值」,作為key來搜尋map是否已出現過與當前元素值可以相加乘target的數。
如果有找到,則將map的index以及當前的index作為結果return,因為可以假設只有一組解。
如果未找到,將當前值作為key、當前的index作為value新增到map中。
(大略說完後,一邊寫扣一邊配合註解並解說)
我完成了,請問有什麼問題嗎?
看起來也不錯,那這個方法為何節省了時間?
因為用map的方式,這使得vector內的值只被掃過一次即可明白解出現在何處,不必跑2次迴圈,時間複雜度變成了。
好,那我們就繼續下一題吧。
給予一個大小為n,僅含整數integer的vector,尋找出在這個vector中是哪個值出現超過n/2次?
你可以假設必定存在一個數字出現超過n/2次。
也就是說,比如我有一個vector內含[2,5,7,7,7,7],如我螢幕上所示,那麼預期得到的結果是7嗎?
是的沒錯。
再假設我有一個vector內含[2,-9000000,2,25,7,-7,2,48763,2,2,2],如我螢幕上所示,答案則為2嗎?
這也正確,正負數都會出現。
感謝,我想可以先對vector做一個排序,使得相同的數字會連續在vector中,又且因為必定有超過n/2個元素是相同的,那我們則可以知道vector[n/2]這位置必定存在答案。
聽起來不錯,開始實作吧。
(一邊寫扣一邊配合註解並解說)
我完成了,請問有什麼問題嗎?
那對於本解法,你覺得時間複雜及空間複雜度應該為多少呢?
因為一開始就sort過一次,所以至少為,剩餘的步驟只是遍歷了一次vector,所以是,那麼總結下來,時間複雜度就是。
空間複雜度則為,額外1個變數、,也就是。
好,那麼我們希望在維持空間成本依舊在的狀況下,我們將執行效率再次提升,希望可以達到線性執行時間,你有什麼想法嗎?
(做事、想一下)我觀察到,若必定存在最大元素的話,將其稱為A,同時刪除一個非A及一個A的元素似乎不對結果造成影響,同時刪除兩個不同的非A元素也不會對A造成影響。這或許是關鍵。
如果我只遍歷一次vector,並設立一個計數器count及一個紀錄元素值的變數major,
計數器為0的時候,將計數器加1,並將當前的元素放入major。
當major元素與當前遍歷元素一致,則count+1。
當major元素與當前遍歷元素不同,則count-1。
如此一來,遇上不同的元素時,等於同時刪除兩個元素各一次,遇到相同元素時則記錄當下還剩下多少major元素。
最終,遍歷完成後,major變數內必定剩下我們要求的解。
(一邊寫扣一邊配合註解並解說)
我完成了,請問有什麼問題嗎?
看起來相當好。那我們再進入下一題。
延伸閱讀:
Boyer-Moore Majority Vote Algorithm
Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
Only the filled cells need to be validated according to the mentioned rules.
If a place is empty, it will be filled with "."
In my first thought,I will loop over the Sudoku board and skip all the place that not filled with number.
When current index is a number,start to check the row,the col and the 3 x 3 box that it belongs to.If once detect the duplicate number, instantly return false
If looping is over,result should get true.
ok, that is a solution,but I think this solution pass vector data too many times?Do you have any thought about reducing the data reading times and speed up validating the Sudoku board?
Sudoku board have 9 row,9 colunm and 9 sub 3 x 3 box,may I can use 3 vector to record number that already appeared in each row,colunm and sub box.
in the vector store a short and use bit 1 to bit 9 represent whether number 1 to 9 is already appeared or not.
now start looping the board,every time I detect a number,go to check the vector element corresponding to row,colunm and box of current index.
For example,if element in current index is 5, minus it with '0' to get ASCII Difference,then left shift 1 five bits, bitwise and with corresponding row,colunm and box vector element,if true,means number already appeared,just return false.If false,bitwise or with corresponding row,colunm and box vector element to update.
so we can just only read each element on board once,achieving the speeding up.
That sounds good,you can start implementing it.
(coding while explaing)
OK,finish,Could you have any concern?
I think this is the good method,that's today's interview,thanks for your cooperation.
ps : 名字取的不錯