黑衣: Interviewer.
白衣: Interviewee.
影片: 施新豐-Crazy: Homework1 (漢/英)
黑衣:
Function input有三個.
- nums, 一個 int陣列.
- numsSize, 此陣列 size.
- target, target value for pair sum.
Function需要回傳陣列中任二個 element的 index, 使此二 element的加總結果剛好為 target value.
(假設 input陣列中只會有一組 element的加總結果會等於 target value, 另外, 不能將陣列中一個 element加總二次.)
白衣:
我將這個問題 formulate成以下.
nums[0] | nums[1] | … | nums[size - 2] | nums[size - 1] | |
---|---|---|---|---|---|
nums[0] | N/A | sum(0, 1) | … | sum(0, size - 2) | sum(0, size - 1) |
nums[1] | N/A | N/A | … | sum(1, size - 2) | sum(1, size - 1) |
… | N/A | N/A | … | … | … |
nums[size - 2] | N/A | N/A | … | N/A | sum(size - 2, size - 1) |
nums[size - 1] | N/A | N/A | … | N/A | N/A |
這樣是為了 enumerate陣列中任意二個 element的加總結果, 而就在每個 pair的加總過程中順便比對是否有與 target value相同, 找到的話就 return. 若是所有 pair在 enumerate過後都沒有等於 target value的結果, 就代表陣列中找不到符合條件的 element pair.
有通過 Leetcode whole test cases的驗證.
在老師的作業要求中有看到面試範例影片提到可以使用 Hash來改進, 猜測可以這樣進行 implementation.
在 enumerate完所有與 element 0, e.g., nums[0], 若都沒找到等於 target value的 pair的話, 進行 element 1的 enumeration時, 同樣需要再次存取 nums[2], …, nums[size-1]. 因此, 或許可以在第一次讀取陣列時進行這些動作.
difference(i, j) = nums[j] - nums[i]
的內容.difference(0, 1)
, difference(0, 2)
, …, difference(0, size - 1)
.__target = target - nums[i]
, 這時 __target
就需要在其他 nums[j]
中尋找, where j != i.nums[i + 1]
時, __target += difference(i, j)
, 然後使用這一 round的 __target
與陣列內容作比對即可. 這樣一來, 就不用再讀取 enumeration element i時已讀取過的 element value.太晚開始做作業, 時間很趕. 第一次接觸 Leetcode, 比想像中的還有挑戰性. 有時間的話, 會想完成 Other proposal, 然後比較不同設計的優缺點.
黑衣:
Function input只有一個.
- rowIndex, 一個大於等於 0的 int.
Function需要回傳第 rowIndex列的 Pascal's Triangle的內容.
(0 <= rowIndex <= 33)
白衣:
By definition, Pascal's Triangle中每個 element的值可從其前一列的 element的值來決定. 但這就代表要得知第 n列的內容, 需要把第 n-1列~第 1列的內容都算完. 我想知道有沒有其他的方法可以直接算出第 n列的內容, 回想起高中數學介紹排列組合的問題. Pascal's Triangle中第 n列的 element內容其實就是 (a + b)^n的結果中按升冪或降冪排列後的, 各項次的係數. 分別是 C(n, 0), C(n, 1), …, C(n, n). 這樣一來, 這個問題就可簡化成排列組合的問題.
排列組合的 Proposal雖可直接算出 Pascal's Triangle任一列的任一 element的值. 但是其運算過程會牽扯到 n!的計算, 程式語言的數值類資料結構都有值域限制, 當 n值一大, 這個 proposal就面臨數值 overflow挑戰.
目前我採取這二個 action來減緩數值 overflow的問題.
有通過 Leetcode whole test cases的驗證.
計算機科學與數學還是存在一些差異, 且計算機科學起步之時, 往往是計算資源非常侷限的時代, 難怪會需要有 dynamic programming等演算法, 時至今日, 這些演算法也許不能一步將結果計算出來, 但卻較有延展性, 即便 n值怎麼改變, 較不會引發數值 overflow的問題, 而能逐步將結果算出來.
時間夠的話, 我會想要完成這些.
太晚開始做作業, 時間很趕. 第一次接觸 Leetcode, 比想像中的還有挑戰性. 有時間的話, 會想完成 Other proposal, 然後比較不同設計的優缺點.
黑衣:
Function input有二個.
- dividend, 被除數, or 分子, int型別.
- divisor, 除數, or 分母, int型別.
Function需要回傳 dividend除以 divisor的商數 quotient.
(divisor不會是 0. 若 quotient大於 2^31 - 1, 回傳 2^31 - 1. 若 quotient小於 -2^31, 回傳 -2^31.)
白衣:
我的想法很簡單, 先從 dividend與 divisor都是正數的情況下做思考, 這個情況下, 設計一個 while loop, remaining的初始值設定為 dividend. if remaining >= divisor, 就進入 while loop中把 remaining扣掉 divisor得出新的 remaining, 當 while loop終止時, while loop的執行次數就是 quotient的值.
接著考慮正負號的問題. 我會希望計算時都是以正整數來執行, 所以會需要將 dividend, divisor都轉成絕對值.
我設計一個 sign變數, 初始值為 1.
這就使得可以使用 sign == 0來判斷最終 quotient會是負數.
但這邊還會有另一個問題, int型別的正負數不對稱, 負整數有多一個 -2^31. 我目前的解法是將 dividend, divisor的絕對值都使用 long type來儲存.
然後, 不知道 Leetcode是不是會將 Medium難度的答案增加執行時間的標準. 以下這幾個 special case其實可以有更快的判斷方法.
再來, 我 submission時還是被回覆 Time Limit Exceeded! 因此, 會需要來處理 dividend >> divisor而使得 while loop需要跑多 round的問題.
我希望當 remaining還很大時, while loop中每次可以直接扣掉多次的 divisor, 節省 while loop執行次數. 因此我預先設計了 1~8倍的 divisor, while loop會先從 8倍的 divisor對 remaining進行扣除, 之後才是小於 8倍的 divisor.
有通過 Leetcode whole test cases的驗證.
感覺對於 while loop中 divisor的設定可以更 smart一點, 我認為可以透過 abs(dividend), abs(divisor)的 MSB來動態決定 divisor的大小. 但我目前對 bit operations還不熟悉, 且時間很趕, 就沒有對此進行研究了.
太晚開始做作業, 時間很趕. 第一次接觸 Leetcode, 比想像中的還有挑戰性. 有時間的話, 會想完成 Other proposal, 然後比較不同設計的優缺點.