---
# System prepended metadata

title: 資訊科技產業專案設計(HW2)

---

# 資訊科技產業專案設計(HW2)


## **作業(二)**
##### ***Author : 瞧滷肉GIOGIO***

## ***2. Add Two Number*** 
    
* **Description** : 給定兩個linked list 陣列中如果出現順序為 1 -> 2 -> 3 代表為321，將兩個陣列加起來後return 新陣列的linked list，舉例 1 -> 2 -> 3 加上 2 -> 4 -> 6 -> 4 輸出 3 -> 6 -> 9 -> 4 因為 321 + 4642 = 4963
    * **Solution**
        - 利用兩個指針分別指向 linked list
            1. 進位數
            2. 然後用雙指針各自往下
            3. 把值加起來個位數當成 $node.value$ 而進位數就一定是十位數
            4. 每次都創造一個 $node$ 存下 $node.value$
            5. 如果其中一個 $node$ 到 $null$ 就停止，把$res$指向另外個答案 
            6. 判斷進位數跟後面答案就直接用加法持續修正
            7. return答案
        - 兩個Linked List 長度分別 $n$ ,$m$ 
    * **Complexity Analysis**
        - 時間複雜度為$O(max(n,m))$
        - 空間複雜度為$O(max(n+m)$
    ```python
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:

            add = 0 
            head = ptr = ListNode()

            while l1 and l2 :
                currentNode = ListNode()
                currentTatol = l1.val + l2.val + add 
                currentValue , add = currentTatol%10 , currentTatol//10
                currentNode.val = currentValue

                ptr.next = currentNode
                ptr = ptr.next
                l1 = l1.next
                l2 = l2.next

            while l1 :
                currentNode = ListNode()
                currentTatol = l1.val + add 
                currentValue , add = currentTatol%10 , currentTatol//10
                currentNode.val = currentValue

                ptr.next = currentNode
                ptr = ptr.next
                l1 = l1.next

            while l2 :
                currentNode = ListNode()
                currentTatol = l2.val + add 
                currentValue , add = currentTatol%10 , currentTatol//10
                currentNode.val = currentValue

                ptr.next = currentNode
                ptr = ptr.next
                l2 = l2.next
            if add :
                currentNode = ListNode()
                currentTatol = add 
                currentValue = currentTatol%10
                currentNode.val = currentValue
                ptr.next = currentNode

            return head.next
    ```
    * **Solution(優化)** 
        - 利用原本的linked list 作為儲存空間對資料修改，故不需要額外空間，空間複雜度可降低到$O(1)$
    ```python
            # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:

            add = 0 
            head = ptr = l1
            prev = ListNode()

            while l1 and l2 :
                currentTotal = l1.val + l2.val + add 
                currentValue , add = currentTotal%10 , currentTotal//10
                l1.val = currentValue 
                prev = l1
                l1 ,l2 = l1.next ,l2.next

            while l1 :
                currentTotal = l1.val + add 
                currentValue , add = currentTotal%10 , currentTotal//10
                l1.val = currentValue
                prev = l1 
                l1 = l1.next

            if l2:
                prev.next = l2 
                while l2 :
                    currentTotal = l2.val + add 
                    currentValue , add = currentTotal%10 , currentTotal//10
                    l2.val = currentValue
                    prev = l2
                    l2 = l2.next

            if add :
                lastNode = ListNode(add)

                prev.next = lastNode

            return head

    ```
    * **對話草稿**
    ```
    🦍: interviewer
    🐵: interviewee

    🦍: 你好，我是今天參與SuperSecurity超安公司的senior SWE Argo，很高興今天你過來進行這場面談，
    那希望你用輕鬆的狀態來面對這場面試，過程中可以盡量展示你的想法，那首先先介紹一下你自己，可以嗎
    🐵: 你好，我叫做Sandow Monky，很高興認識你，很期待今天的面試，請多多指教
    🦍: 好的，那首先思考一下一個場景，台七億公司有一個機密文件，那該公司有兩個部門會access該文件，分別是技術部門跟行銷部門，以下簡稱T跟S
    "T"代表technical，"S"代表Sales，"T"，"S" 部門有不同階級的主管，數量也不一定相同，但要access該文件有一個條件，要從T部門的主管的資料庫中按照順序排出他們的安全碼
    接著"S"同理，然後安全碼從"T","S"各自最低階開始往上進行加法進位，所以真正的password不能夠通過單一主管去知道正確答案。
    1.注意"安全碼的排列並非照階級，而是由加密系統隨機assign下個主管"，所以是個別存在每個主管的profile中，
    而你是一名商業駭客，你已經透過某些方法取得他們資料庫的權限
    2.但問題是就算找出安全碼，實際場域可能會出現超複雜的密碼串，而資料庫的開啟是有時效性的，系統不允許同一個人開啟profile在一天之內超過1分鐘，所以一旦出現這種狀況系統會直接鎖死文件並重新分配安全碼
    3.你今天運氣很好，僱用你的商業對手獲得他們各自的最低階人員密碼跟權限，賺完這一票保證可以讓你躺平買在台北市蛋黃區，但被系統抓到你的雇主肯定不會認帳，你就會進土城躺好躺滿
    🐵: 好的，這裡如果想破解這個問題，是否可以先假設安全碼的範圍再一個區間呢
    🦍: 可以這一題你可以先假設每個人安全碼落在0~9之間
    🐵: 根據剛剛所說這一個我們可以類比成兩道linked list的題目，而最低位數必須由最後一個人得到，然後最後對兩個串列進行加法。
    請問這樣的理解有問題嗎?
    🦍: 沒問題，但這裡要注意打開linked list是有時效性的，看完之後必須馬上關掉
    🐵: 好的，我會注意那我會先利用一個進位數維持進位值，然後做完加法後移動pointer到下一個profile，同時create一個list來記錄該位數，
    因此我會利用以下方法...
    🦍: 好的你可以先實作這個算法並且分析一下時空間複雜度
    🐵: coding...
    🐵: 這個算法的時間是O(n) ，而空間則是O(n)
    🦍: 好，但今天這個系統有進行更新，單純進行存取是不允許在額外空間create一個linked list，這聽起來很合理對吧，畢竟讀取資料又可以新建一整個profile本身就是很奇怪的事情，給你一個提示，每個profile中其實有個備註欄你可以偷偷的使用，系統不會發現因為那是屬於個人的隱私權
    🐵: 了解，所以該做法可能必須要改進到空間O(1)才行，以下是我的算法
    🦍: 恩恩，很好，謝謝你提供的算法，那有關面試結果我們會再這周給你答覆，謝謝
    🐵: 好的謝謝!

    ```
 
* **自我評量**
    * 針對interviewer
        * 有點提示太明顯，且作圖時就已經幾乎把背後要使用的概念展現出來了
    * 針對interviewee
        * 講話贅詞太多，盡量減少痾..或這個..，或是使用不確定的用詞(如或許可以)，可以不一定要為了不發生空窗而一直說話，可以提出讓我思考一下來整理思緒。
        * 應該主動提出優化程式碼的提議，雖然第一步寫出lengthy code幾乎是不可避免，但過程中也可以對可能需要優化的部分加以註解。以利後續可能會出現的延伸問題




## **他評筆記**

## 月退 - Leg

#### ***1. Two Sum***
* hashmap解在空間複雜度應為O(n)，因為本題interviewee 是先把(nums[i],i)作為(key,value)存入dict，此步驟就已經會占用O(n)
* 更好的解法也是利用hashmap一步一步存，每次先檢查dict是否有存在一個答案，如果有就把答案的value取出直接return，但複雜度其實也是跟interviewee差不多

    #### 針對 interviewer 檢討
    * 這題interviewee 聽完面試者解答可以透過修改two sum，告訴interviewer說真實狀況有可能出現很多種的配對，所以nums中是有機會出現重複數字，請interview講解應如何列出所有可能的答案，作法其實就是修改字典中value唯一個list 或C++中的array

    #### 針對 interviewee 檢討
    * 因為說實在第一次遇到這題講出hashmap最佳解其實應該都是之前寫過XD，所以可以假裝不知道最佳解，先用暴力解(雙迴圈)，來讓面試官有討論的空間

#### ***9. Palindrome Number***
* 講解不錯，不論是暴力解或者用字串反向的解講都可以讓完全不知道狀況的人，很容易明白

    #### 針對 interviewer 檢討
    * 或許可以在問一下複雜度會不會細微差異，因為方法(一)利用迴圈 + 數學計算 方法(二)則是把字串切開反向然後比對，

    #### 針對 interviewee 檢討
    * 可以簡述一下方法二的空間複雜度運用，會讓interviewee 知道interviewee對python語言的熟悉度


#### ***2. Add Two Numbers***
* 題目解法很直覺，但整體仍有優化空間

    #### 針對 interviewer 檢討
    * 程式碼的提問很細節，可以讓interviewer明確知道interviewee有follow到 
    * 可以提示interviewee其實本題第一個一定是個位數，

    #### 針對 interviewee 檢討
    * 可以再提出**優化**，事實上 linkedlist1 : 5->2->3 linkedlist2 : 6->1->7 ，第一位一定是最小值，作法可以如下
        1. 進位數
        2. 然後用雙指針各自往下
        3. 把值加起來個位數當成 $node.value$ 而進位數就一定是十位數
        4. 每次都創造一個 $node$ 存下 $node.value$
        5. 如果其中一個 $node$ 到 $null$ 就停止，把$res$指向另外個答案 
        6. 判斷進位數跟後面答案就直接用加法持續修正
        7. return答案
    * **上述缺點** 
        * 比較不直覺且寫法也比較要考慮多一點，時間複雜度也沒有優化太多，但可以偷一點時間，最佳狀況就是根本沒有進位結果後面還有一大串，此時就可以直接指過去當return 

## 霍夫曼-Mark Hoffman

#### ***268. Missing Number***
* 針對暴力解的優化展現interviewee對C++語言操作上的靈活性，且在優化解上也利用數學方式減少空間複雜度的運用

    #### 針對 interviewer 檢討
    * 對interviewee的提示不會太多也很剛好，連續暗示兩次還有更好得記憶體優化解法

    #### 針對 interviewee 檢討
    * 解法的展現有表現出語言、跟陣列型態操作熟悉度，對題目的理解背後數學意義也能很快跟上


#### ***387. First Unique Character in a String***
* 面試者對題目理解很清楚之外，在影片開頭中展現的示範也有利interviewer去知道面試者的理解進度

    #### 針對 interviewer 檢討
    * 對interviewee的引導方向跟講解都很清楚明白。

    #### 針對 interviewee 檢討
    * 暴力解跟優化解都有提出對應的作法，也展現使用C++ stl的理解程度，包括本題因為是存入字母故實際上不可能用$log(n)$，也簡潔的提出說明。


#### ***16. 3-Sum Closest***
* 對暴力解跟優化解都有提出對應作法，且都有給出合理的複雜度解釋

    #### 針對 interviewer 檢討
    *  當面試者提出$O(n^2)$ 可以適時的提點面試者，因為本來就會預期大概在submit階段過不了

    #### 針對 interviewee 檢討
    *  暴力解可以利用圖示帶過，因為跑在leetcode上面某些狀況就算是對的也有可能過不了
    *  優化解的分析很好，對完全沒寫過的人來說仍然是蠻好理解的


## 火箭-Raccoon 
#### ***34. Find First and Last Position of Element in Sorted Array***
* 暴力解跟最佳解都有明確寫出跟講解。尤其是暴力解有稍微在最後聊一下解法

    #### 針對 interviewer 檢討
    * 可以對二搜法的變體提出一些疑問觀察interviewee的回應。

    #### 針對 interviewer 檢討
    * 寫完暴力解code後有在針對code說明清楚code中各項數字的意義，對聽者有強化對解法的理解
    * 最優解運用2個binary search，找出最左跟最右，但因為binary search是基礎觀念，而本題是運用二搜法並做出細部調整，對於第一次看到寫法的人可能會有發不出差異的狀況，可以像暴力法講解，在結束coding在聊一下細部的操作。

#### ***141. Linked List Cycle***
* 快慢指標跟Hashmap方法的複雜度都有提出解釋，而且還比較各自優缺點

    #### 針對 interviewer 檢討
    * 可以針對C++ Stl使用時是否對複雜度產生影響進行分析

    #### 針對 interviewee 檢討
    * 針對題意理解可以用畫圖講解

#### ***70. Climbing Stairs檢討***
* 這是經典的遞迴練習題，可以透過iterative去遍歷得到最佳解，個人覺得答案很好，但解釋上或許可以搭配圖案或是給出範例來強化解題的概念
    #### 針對 interviewer 檢討
    * 當interviewee講出複雜度時可以去細問為何why?因為此類型的題目太經典，光是用背的其是就可以背出複雜度，如果細問下去就可以去區分面試者對複雜度的理解
    #### 針對 interviewee 檢討
    * 解釋複雜度可以花一些時間表演出對複雜度分析的概念。

## 肯尼-Ken 
#### ***26. Remove Duplicates from Sorted Array***
* 影片非常用心!!!!還有上字幕而且英文講解非常的清楚，但[6:11](https://youtu.be/bIYaaTPyI30?t=371) 剪輯好像有點失誤，都沒有聲音
    #### 針對 interviewer 檢討
    * 最佳解提示有點太明顯幾乎等於大暴雷
    #### 針對 interviewee 檢討
    * 程式寫法很簡潔很容易就能理解算法的核心內容.
    
#### ***94. Binary Tree Inorder Traversal***
* 解釋很清楚，但實作上應該不需要try ... except .. 因為不太可能會有error或無法預期之狀況出現

#### ***152. Maximum Product Subarray***
* 暴力解跟最佳解都有提出合理的作法，解釋也很能理解
    #### 針對 interviewer 檢討
    * 在批評出暴力解太慢之前，應該請面試者去分析一下複雜度，畢竟第一道解法通常都是最直覺的暴力解，也可以去了解面試者對演算法分析的理解度
    #### 針對 interviewee 檢討
    * 講解題目可以用一些資料結構術語去說明，比如DP解法，這樣聽者如果是有相關背景知識就會很容易catch上講者的解題思路 
    * 此題DP解就是maintain **最大(正值)** & **最小值(負值)** 去紀錄可能的最佳解，也可以去說明一下這樣寫法的時間or空間複雜度


## 靈魂程式手-Soul Coder
#### ***2. Add Two Numbers***
* 面試者在解題的想法有考慮到題目設計，而不是單純加起來然後反向然後輸出linked list
#### ***1646. Get Maximum in Generated Array***
* 雖然本題光看題意就直覺想到DP，或許講解DP的概念，也可以說明一下該題的範例中Dynamic Programming
    #### 針對 interviewer 檢討
    * 雖然是easy的題目但仍然可以詢問為什麼要利用DP的概念，以及如果給定某些情境下，DP作法的優缺點。
    * 可以請面試者優化程式碼
    #### 針對 interviewee 檢討
    * interviewee第一眼就看出用DP解確實蠻合理，因為題目就寫在那，但如果從表演層面或許可以聊一下DP，或是給出一些範例說明。
#### ***20. Valid Parentheses***
* 經典的stack題型，解法上也沒什麼問題
    #### 針對 interviewer 檢討
    * 因為基礎題型太簡單，或許可以變化一下說是否加入一些計算式子在中間

