# 2023 年「[資訊科技產業專案設計](https://hackmd.io/@sysprog/info2023)」作業 2 #### 查理-Charlie #### :rabbit: : 我 #### :koala: : 面試官 [影片連結](https://youtu.be/79sx6w13hC8) ## <font color="#7C8CD4">**206.Reverse Linked List**</font> ### **模擬面試過程** #### :koala: : 題目會給你一個指向一組Linked List的指標叫做 head,請你將這組Linked List進行反轉,並且回傳反轉後的Linked List。 #### :koala: : 請問你對題目有疑問嗎? #### :rabbit: : 有的,我想詢問關於輸入的Linked List 的邊界條件? #### :koala: : 輸入的Linked List 中其節點數的範圍是0~5000。 #### :rabbit: : 好的,爲了確認我對題目的理解,我想用一個例子説明。這道題讓輸入的Linked list 反轉,就是讓每個node 指向下一個node的指標反方向。 ![](https://hackmd.io/_uploads/Hk4BYKUZp.png) :::info 輸入: [1,3,5,7,9] 輸出: [9,7,5,3,1] ::: #### :rabbit: : 並且在結尾的node指向的下一個node 必須給定NULL,才能確定到了linked list 的最後。 #### :rabbit: :請問我對題目的理解正確嗎? #### :koala: : 正確,你可以開始寫你的程式了。 #### :rabbit: : 在寫程式之前,我想先講一下我的想法。 #### :rabbit: : 首先,我想到的是使用遞迴法來做這道題。我會將除了第一個節點的其他節點全部反轉,再接上原先的第一個節點,再接上NULL。 ``` class Solution { public: struct ListNode* reverseList(ListNode* head) { if(head == NULL || head->next == NULL){ return head; } struct ListNode* prev = NULL; struct ListNode* newhead = reverseList(head->next); head->next->next = head; head->next = prev; return newhead; } }; ``` #### :rabbit: : 使用這個方法的空間複雜度為O(n),時間複雜度也是O(n)。 #### :koala: : 除了用遞迴的方法之外,你覺得你還能用更好的方法解決這道題嗎? #### :rabbit: : 第二種方法我想到的是使用迭代法來做這道題。我會先宣告 3 個 node 指標:newhead、cur、next。cur 指向我們當前需要反向的 node,而 newhead 則是指向上一個反向完的 node,至於 next 則是先指向當前 node 在反向前所指向的下一個 node。 ``` class Solution { public: struct ListNode* reverseList(ListNode* head) { struct ListNode* newhead = NULL; struct ListNode* curr = head; while (curr != NULL){ struct ListNode* next = curr->next; curr->next = newhead; newhead = curr; curr = next; } return newhead; } }; ``` #### :rabbit: : 這個方法中我只宣告了 3 個指標,所以空間複雜度為O(1)。因為需要走訪每個 node 再改變他們指向的下一個的指標,所以時間複雜度為O(n)。 #### :koala: : 好的,謝謝你的作答。那我現在改變一下題目,我依然會給你一組Linked List,請你寫出可以判斷這組Linked List 是否回文的程式。請問你有任何問題嗎? #### :rabbit: : 有的,我想請問這組 Linked List 的邊界條件? #### :koala: : :Linked List 中的節點數範圍為1~10000。 #### :rabbit: : 好的,爲了確認我對題目的理解,我想用一個例子説明。 :::info 輸入: [1,3,5,3,1] 輸出: true 輸入: [1,3,5,7,9] 輸出: false ::: #### :rabbit: :請問我對題目的理解正確嗎? #### :koala: : 正確,你可以開始寫你的程式了。 #### :rabbit: : 在寫程式之前,我想先講一下我的想法。 #### :rabbit: : 首先,我會先將Linked List反轉,接著再逐一比較反轉後的Linked List 和原先的Linked List 是否一模一樣,如此便可以知道是否為回文。 ``` class Solution{ public: bool isPalindrome(ListNode* head){ if (head == NULL||head->next == NULL) { return head; } ListNode* newhead = NULL; ListNode* curr = head; while(curr!=NULL) { ListNode *temp = new ListNode(curr->val); temp ->next = newhead; newhead = temp; curr = curr->next; } while(head && newhead) { if (head->val != newhead->val) { return false; } head = head->next; newhead = newhead->next; } return true; } }; ``` #### :rabbit: :使用這個方法的空間複雜度為O(n),時間複雜度也是O(n)。 #### :koala: :好的,謝謝你。 --- ### **模擬面試檢討** ### <font color="#7C8CD4">**自評**</font> interviewer: 1. 口齒可以更加清晰。 interviewee: 1. 口齒可以更加清晰 2. 說話聲音再大一點 3. 一邊打程式一邊解說時,聲音會越來越小。 4. [3:12](https://www.youtube.com/watch?v=47nKdqIsUuU#t=3m12s) [4:10](https://www.youtube.com/watch?v=47nKdqIsUuU#t=4m10s)打錯字(正確: head、reverseList),應該多練習打程式的速度和正確率 --- ### <font color="#7C8CD4">**第一次作業的收穫**</font> interviewer: * 優點 1. 有開場白,可能會先介紹自己是哪一間公司...,先和interviewee稍微互動後才進入題目 2. 題目有做變形,延伸到一些真實情況上 interviewee: * 優點 1. 口齒清晰,聲音自然,語速穩定 2. 解釋程式時的思路清楚 ### 第四次作業 他評01 * [3:30](https://youtu.be/79sx6w13hC8?t=208)人的收音不好,音量偏小,另外像[16:17](https://)~[16:27](https://)這邊聲音都糊在一起,而且整個面試出現很多次機車、汽車經過的聲音,需要換去更安靜的房間面試、窗戶關小一點,或是找降噪方法。 * [2:03](https://youtu.be/79sx6w13hC8?t=123)、[4:06](https://youtu.be/79sx6w13hC8?t=246) reverse都拼錯字了。 * [7:07](https://youtu.be/79sx6w13hC8?t=421 )講複雜度O(n)卻忘記講為什麼,給人感覺像用背的。不過後面說明遞迴解法的複雜度時就有記得講原因,讚。 * [7:08](https://youtu.be/79sx6w13hC8?t=428 )interviewer問的是「更好」的方式,interviewee回答迭代法後卻沒有比較以上兩個方法說明為什麼迭代更好,interviewer好像也忘記自己說過要找更好的解法,直接就進入下一題。我覺得可能的回答可以說空間複雜度更低。 * [7:31](https://youtu.be/79sx6w13hC8?t=442)講的是三個「指標」,但後面code時就講成「指針」了。 * 因為[21:04](https://youtu.be/79sx6w13hC8?t=1264)已經實際代入[13531]這個例子說明那段程式碼可以反轉linked list,那[23:08](https://youtu.be/79sx6w13hC8?t=1388)[13579]的例子我想就不用再詳細代進程式碼走過這部份了,因為也只是反轉而已,重複性太高了,可以直接跳去講判斷不是回文回傳false那部分。 * [24:48](https://youtu.be/79sx6w13hC8?t=1487)複雜度沒有講原因。 ### 第四次作業 他評02 + intervewee + [7:00](https://youtu.be/79sx6w13hC8?t=1487)通常面試在分析時間複雜度的時候應該說明為何他的時間複雜度是O(N),而不是直接說O(N)就帶過,應該要逐步說明每一行程式碼操作所需要的時間複雜度來做說明。 + interviewer + [2:00](https://youtu.be/79sx6w13hC8?t=1487)題目設計的時候應該盡量避免直接講出 reverse linkedlist這種關鍵字,舉例:當我們需要用非連續記憶體空間記錄一串資料的時候,你會使用何種資料結構去儲存?進一步延伸到如果我們需要順序性來取得空間內部的資料,以及如果順序性需要反轉的話你會如何實作?這樣才可以避免背答案怪人。