貢獻者: 李一 Pear
模擬面試錄影-1 (英)
模擬面試錄影-2 (漢)
模擬面試錄影-3 (漢)
interviewer: 今天你出門旅遊,遇到了一條河,你想要過去對岸,但是河的水很深,這時你看到旁邊有一座吊橋,吊橋的路是由一片一片的木板組成,你可以選擇一片一片走,或是跨一片走,那請問你總共有幾種不重複的走法到對岸?
interviewee: 假設總共吊橋的路有n片地板的話,除了橋上的路以外還有現在踩的地方跟對岸,總共n+2個立足點,所以一開始我會先宣告一個長度為n+2的陣列,由於到達現在的位置和第一個木板的方法都是只有一種,所以陣列的第一個還有第二個元素都是一。
第二片木板可以從起始點或是第一片木板到達,所以到達第二片木板的走法數量會是到達起始點跟第一片木板的走法數量的總和,依此類推,所以如果要算出到達第i點的走法數量,就需要將到達i-1以及i-2的走法數量加起來。
interviewer: 使用了一個陣列儲存了你到各個位置的走法的數量,但是好像不需要把他們全都記錄下來,是不是有更好的方法能降低你的空間複雜度呢?
interviewee: 利用兩個變數current跟previous來取代陣列,一開始一樣先將current跟previous設為1,接著使用for迴圈,先讓temp=current,接著讓current=temp+previous,然後讓previous=temp,迴圈結束後再回傳current。
interviewer: 有一串正整數數列,將數列中的元素用這個元素後面的元素中的最大的元素取代。
interviewee: 從第一個元素開始找後面的最大元素。
interviewer: 每一步都要向後找最大的元素會不會太過於耗時?
interviewee: 如果同時記錄最大元素的位置,直接將前面的元素替換成找到的最大元素,可以節省一些時間。
interviewer: 如果今天我給你一個遞減的數列,像是[5 4 3 2 1],這樣你兩個方法所需要的時間其實是一樣的。
interviewee: 如果從數列的尾端開始,一開始先宣告一個變數,值為數列的最後一個數值,然後從數列到數第二個開始往前,比對當前數列位置的值與變數的大小,如果比變數小的話,就替換成變數的值,比變數大的話,就將變數的值變成該位置的值。
interviewer: 在處理數列最後一個數應該有更好的處理方法。
interviewee: 在程式中會先將數列中的數字替換掉,再去比對變數的大小,這樣的話,我一開始就可以將要替換進去的變數設為-1,這樣的話迴圈可以從n-1開始,程式最後將數列最後設為-1可以去掉。接下來也不需要一個變數n儲存數列長度,下面迴圈可以直接將n-1替換成arr.size()-1。
interviewer: 有一個機器人,只能往右或往下移動,這個機器人有幾種方法移動到房間右下角呢?
interviewee: 可以簡化成一個排列組合的問題,由於機器人只能往下或往右走,加上這個房間是長方形的,假設這是個m*n的房間,機器人需要m-1步到達房間最下面,需要n-1步到達房間最右邊,那總共有m+n-2階層除以m-1階層再除以n-1階層這麼多種方法。
interviewee: 先宣告一個 的二維陣列用來儲存機器人到各個位置的走法數,陣列的第一排跟第一列都先初始化為1,由於機器人到位置(i, j)只能從(i-1,j)或是(i, j-1)出發,所以機器人到位置(i, j)的走法數會是機器人到位置(i-1, j)跟(i, j-1)的走法數的和。
interviewer: 如果使用遞迴的方式會遇到什麼問題,以及如何改善呢?
interviewee: 在遞迴的過程中,我可能會多次重複走訪過陣列的某一個點,為了避免這種情況,在一開始我可以將陣列中的值初始化成-1,這樣在遞迴的程式中,可以透過該點數值是否為-1,來判斷是否走訪過這個位置。