# 2023年 資訊科技產業專案設計 作業1 > contributer: 哈囉-Hi > video: [1](https://youtu.be/wCLCpmhdKxw), [2](https://youtu.be/nRBLQ3-U8Ww), [3](https://youtu.be/xccI0_yKEHU) > :man: imterviewer :woman_in_lotus_position: interviewee ## [Maximum Average Subarray l](https://leetcode.com/problems/maximum-average-subarray-i/?envType=study-plan-v2&envId=leetcode-75) :man:: Hi , I'm Jo. Here's a question for you . Given an integer array **num** consisting of **n** elements , and an integer **k**. Find a contiguous subarray whose **length is equal to** **k** that has the maximum average value and return this value . Any answer with a calculation error less than **10^-5^** will be accepted :woman_in_lotus_position: : You means that I got an array and an integer , then I need to do the calculation to find the continuous part that contains four elements? :man:: Yeah , I think that's a great explaination . :woman_in_lotus_position:: Well , I would like to use two for loop , one for the iteration of the entire array , the other for the calculation to sum up the elements in the subarray :man: All right. It sounds reasonable. :woman_in_lotus_position: : Ok , I would like to start with giving some examples ``` Input : nums = [1,12,-5,-6,50,3] , k = 4 there are three subarray [1,12,-5,-6] , [12,-5,-6,50] , [-5,-6,50,3] with the sum be 2 , 51 , 42 with avg be 0.5 , 12.75 , 10.5 ``` :man:: I am wondering if there's a quicker solution? :woman_in_lotus_position: : Umm...maybe I could use the sliding window to remove the first element in the current subarray and add the next element behind the last one in current subarray >程式碼 1.original ```cpp class Solution { public: double findMaxAverage(vector<int>& nums, int k) { double Max = 0; //max for the biggest value double part = 0; //part for the sum of each loop //loop through the array to find the max for(int i=0; i<= nums.size()-k ;i++){ part = 0; for(int j=i; j<k ; j++){ part+= nums[j]; } if(part>Max) Max = part; } return Max/k; } }; ``` 2.sliding window ```cpp class Solution { public: double findMaxAverage(vector<int>& nums, int k) { double Max = 0; //max for the biggest value double part = 0; //part for the sum of each loop //loop through the array for(int i=0; i<= nums.size()-k ;i++){ if(i==0){ for(int j=0; j<k ; j++){ part+= nums[j]; } Max= part; } else{ // slide the calculation window part = part - nums[i-1] + nums[i+k-1]; if(part > Max) Max = part ; } } return Max/k; } }; ``` ## [Search in a Binary Search Tree](https://leetcode.com/problems/search-in-a-binary-search-tree/?envType=study-plan-v2&envId=leetcode-75) :man:: The next question is about Binary Search Tree . Now , you are given the **root** of a binary tree (BST) and an integer **val**. Please find the BST that the node's value equals **val** and return the subtree rooted with that node. If such a node does not exist , return **null**. :woman_in_lotus_position: : Ok , so I am given a value and a root of a binary tree . Then , I need to search if there's any node that correspond to the value . If it exists , I should just output the root and the following node with preorder traversal . :man:: All right , please go on. :woman_in_lotus_position:: Let me try to do it with some examples ![](https://hackmd.io/_uploads/ryrrkwOAn.png) in this photo , we find the corresponding value 2 in the trees , and then output the value based on the root with preorder traversal :man:: Yeah , it make sense :woman_in_lotus_position: :Besides , since a BST would have bigger node in the left hand part , and smaller one in the right hand part , so we could use a if else to help it find the targer node quicker >程式碼 ```cpp class Solution { public: TreeNode* searchBST(TreeNode* root, int val) { if(root == NULL) return NULL; if (root->val == val) return root; else if (root->val >val) return searchBST(root->left , val); else return searchBST(root->right , val); } }; ``` ## [Delete the Middle Node of a Linked List](https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/?envType=study-plan-v2&envId=leetcode-75) :man::There is the final question . Given the **head** of a linked list . **Delete** the **middle node** , and return the **head** of the modified linked list. The **middle node** of a linked list of size **n** is the **[n/2]^th^** node from the **start** using **0-based indexing** , where **[x]** denotes the largest integer less than or equal to **x**. :woman_in_lotus_position:: Ok , so I got a size **n** linked list , and I need to get rid of its middle node ? :man:: Yeah , it sounds reasonable . :woman_in_lotus_position: : All right , let me start with some examples. this is the example for odd counts of elements ![](https://hackmd.io/_uploads/S1CFmlsA2.png) this is for even counts of elements ![](https://hackmd.io/_uploads/S1lwcmesC3.png) :man:: Then , how will you code this out :woman_in_lotus_position: : I would start from named a new Listnode as front and tail , and assign the node of head to front , then iterate through head to find the size of this linkedlist . After that , I would go to that node before our target , then link it to the node behind our target , and thus delete the node . Besides , we should keep an eye on the case when size equals to 1 , we should just return NULL . >程式碼 ```cpp /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* deleteMiddle(ListNode* head) { ListNode* front; ListNode* tail; int size = 0; front = head; while(head != NULL){ size++; head = head->next; } head = front; for(int i=1 ; i<size/2 ; i++){ head = head->next; } if (size == 1) return NULL; else tail = head->next->next; head->next = tail; return front; } }; ``` ## 初步檢討 :man: interviewer + **引導解題的方式不夠深入** 對於演算法的精進可以適度給予提示 ,或是引導interviewee去分析不同演算法的時間與空間複雜度,甚至是應用場景的細節 + **延伸原本問題的技巧** 若是能跳脫原本問題的框架,以延伸的想法與interviewee互動,或許更能挖掘出自己想要的人才 :woman_in_lotus_position: interviewee + **寫程式時說話音量太小** 要保持interviewer聽得清楚的音量 ,或是盡量在coding前的解釋補充得更清楚 ,就不需再coding時分心解釋 + **表達流暢度的精進** 會有過多語助詞以及窮詞的狀況,若能流利地表達能給interviwer自己是 well-prepared and confidence 的印象 --- ## 第二次作業-他評 01 ### 關於 interviewer - [ ] 優點 * 咬字清楚 * 舉例簡潔 - [ ] 可改進的地方 * Part 3 [00:20](https://youtu.be/xccI0_yKEHU?t=20): 與其照著 LeetCode 原題來描述,不如針對應用場景,說明為何要找出單向鏈結串列中間的節點 (並釋放記憶體) > 以 [FreeRTOS](https://wiki.csie.ncku.edu.tw/embedded/freertos) 來說,就用鏈結串列來表示動態建立的任務 * Part 3 [3:10](https://youtu.be/xccI0_yKEHU?t=190): 避免只說 "How will you code this out?",這樣的互動太草率,應該回顧 interviewee 提出的方法後,在適當的分析後,才說 "reasnable" * Part 3 [9:54](https://youtu.be/xccI0_yKEHU?t=594): 避免過早說 "That's all",聽起來太敷衍,應該針對程式碼討論,掌握 REACTO 流程,特別是 Test 及 Optimization * Part 3 [10:08](https://youtu.be/xccI0_yKEHU?t=608): 避免過早說 "Look forward",這樣可能會帶來非必要的暗示,應該給予評論和延伸問題 ### 關於 interviewee - [ ] 可改進的地方 * Part 3 [1:53](https://youtu.be/xccI0_yKEHU?t=113): 作為 interviewee,不該直接提及 LeetCode 及其範例,應該要能夠呼應 REACTO 流程 * Part 3 [2:10](https://youtu.be/xccI0_yKEHU?t=130): 在 Google Docs (或者協作的頁面) 中,一邊解說案例,一邊寫下,屆時開發程式時,可對照運用 * Part 3 [2:18](https://youtu.be/xccI0_yKEHU?t=138): 採用 0-based indexing,依據範例應該是左邊 (或右邊) 起算的第 4 個節點,不該說 "the third node"。可用類似以下說法: > In a singly-linked list, when we use 0-based indexing, the first node is considered to be at index 0, the second node at index 1, the third node at index 2, and so on. > So, in the example: 1 -> 2 -> 3 -> 4 -> 5 > The first node (index 0) is 1. > The second node (index 1) is 2. > The third node (index 2) is 3. * Part 3 [2:09](https://youtu.be/xccI0_yKEHU?t=129): 應區分 node 和 element * A node is a fundamental building block of a linked list. It consists of two components: - Data: This is the actual information or value that you want to store in the linked list. - Reference (or Link): This is a pointer/reference to the next node in the sequence (in a singly-linked list) or both the next and previous nodes (in a doubly-linked list). * An element in the context of a linked list generally refers to the actual data or value stored within a node. It's what you retrieve or manipulate when you work with the linked list. > Elements are the meaningful pieces of information that you are storing and managing using the linked list data structure. [ChatGPT](https://chat.openai.com/share/98766992-f0e4-4b91-81d4-b1635ce06168) * Part 3 [2:48](https://youtu.be/xccI0_yKEHU?t=168): 若及早定義 middle,並用偶數奇數來解釋,就可及早切入程式碼。`4 / 2 = 2` 的讀法是 "four divided by two equals two" * Part 3 [3:26](https://youtu.be/xccI0_yKEHU?t=206): 字元太小,應適度放大,有利於後續討論。面試的場合通常不會用 LeetCode 網頁 * Part 3 [4:04](https://youtu.be/xccI0_yKEHU?t=244): `front` 和 `tail` 應該宣告在同一行,便於一面解說一面打字 * Part 3 [5:01](https://youtu.be/xccI0_yKEHU?t=301): "We might not... we cannot do the next progress" 聽起來過於武斷,究竟不記錄鏈結串列的長度到底會怎樣? * Part 3 [5:22](https://youtu.be/xccI0_yKEHU?t=322): 避免頻繁地搖頭,可能會讓人誤會你在多個電腦螢幕之間切換視線,或者旁邊有人給你提示 * Part 3 [5:50](https://youtu.be/xccI0_yKEHU?t=350): 頻繁搖動滑鼠,很討厭,無助於溝通 * Part 3 [6:07](https://youtu.be/xccI0_yKEHU?t=367): "I forget that" 這句話不用說,應該強化 REACTO 流程,讓方法可對應到程式碼 * Part 3 [7:35](https://youtu.be/xccI0_yKEHU?t=455): 關於特例的討論,應該在 REACTO 的 Approach 階段提出 若用 [Linux 風格的 cicular doubly-linked list](https://hackmd.io/@sysprog/c-linked-list) 撰寫,優雅許多: ```c /* Delete the middle node in queue */ bool q_delete_mid(struct list_head *head) { if (!head || list_empty(head)) return false; struct list_head *slow, *fast; slow = fast = head->next; for (; fast != head && (fast = fast->next) != head; fast = fast->next) slow = slow->next; element_t *element = list_entry(slow, element_t, list); list_del(&element->list); q_release_element(element); return true; } ``` ## 第二次作業-他評 02 ### interviewer - [ ] 優點 * 用字簡潔 - [ ] 可改進的地方 * 介紹題目的時候,可以不完全把題目條件講清楚(測資範圍等),讓面試者自行思考極端情況、問清楚條件 * interviewee 完成題目後,可以請對方對演算法做分析,像時間複雜度,或是哪裡可以改進等 (Optimization) ### interviewee - [ ] 優點 * 有把範例用註解寫下來 - [ ] 可改進的地方 * 注意 coding style,固定使用大/小寫當作變數開頭(可能有面試官會在意)