---
# System prepended metadata

title: 2023 年「資訊科技產業專案設計」作業 1

---

# 2023 年「[資訊科技產業專案設計](https://hackmd.io/@sysprog/info2023/)」作業 1
> 貢獻者: 風清揚-Wind
> [模擬面試影片](https://youtu.be/jJTtHZZQsy4)

## [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/)
### 題目描述
給一個裡面僅包含( ) { } [ ] 的字串s，請判斷輸入的字串是否有效。
輸入的字串在以下情況有效 : 
1. 左括號必須由相同類型的右括號封閉。
2. 左括號必須按照正確順序封閉。
3. 每個右括號都有一個對應的相同類型的左括號。
### 程式碼說明
- [ ] 程式碼雛形
這題是要判斷括號有沒有括對，所以在遇到左括號時，都直接存入stack裡面。當遇到右括號，會判斷與stack最後一個element是否是成對的，如果成立，就把stack最後一個元素移除，並把紀錄stack裡面element數量的i減一，若不成立，則直接回傳false。
最後如果stack裡面還有element，回傳false，若沒有則回傳true。
```c
bool isValid(char * s){
    int i=0;
    char stack[strlen(s)];
    for(int j=0; s[j]!=NULL;j++){
       if(s[j]!='}' && s[j]!=']' && s[j]!=')'){
           stack[i]=s[j];
           i++;
       }
       else{
           if(i==0) return false;
           else if(s[j]=='}' && stack[i-1]=='{'){
               stack[i-1]=NULL;
               i--;
           }
           else if(s[j]==')' && stack[i-1]=='('){
               stack[i-1]=NULL;
               i--;
           }
           else if(s[j]==']' && stack[i-1]=='['){
               stack[i-1]=NULL;
               i--;
           }
           else {
                return false;   
           }
       }
    }
    if(i!=0) return false;
    else return true;
}
```

- [ ] 程式碼改善方法
針對特殊情況，可以做出改善，並減少stack的空間。這邊的做法是stack只需要原來空間的一半。再把左括號放進stack裡面之前，先判斷stack裡面的元素是否已經大於輸入字串s的一半，如果成立，代表就算接下來都是相對應的左括號也無法清空stack，所以可以直接回傳false。
```c
bool isValid(char * s){
    int i=0;
    char stack[strlen(s)/2+1];
    for(int j=0; s[j]!=NULL;j++){
       if(s[j]!='}' && s[j]!=']' && s[j]!=')'){
           if(i<strlen(s)/2){
            stack[i]=s[j];
            i++;
           }
           else return false;
       }
       else{
           if(i==0) return false;
           else if(s[j]=='}' && stack[i-1]=='{'){
               stack[i-1]=NULL;
               i--;
           }
           else if(s[j]==')' && stack[i-1]=='('){
               stack[i-1]=NULL;
               i--;
           }
           else if(s[j]==']' && stack[i-1]=='['){
               stack[i-1]=NULL;
               i--;
           }
           else {
                return false;   
           }

       }
    }
    if(i!=0) return false;
    else return true;
}
```

## [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/)
### 題目描述
給定兩個以排序的linked lists (list1,list2)，將兩個linked list合併為一個linked list。該list必須通過將list1跟list2的節點串接在一起來形成。 Return必須回傳串接起來的list的head。
### 程式碼說明
- [ ] 程式碼雛形
```c
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode head;
    struct ListNode* mergelist= & head;
    if(list1==NULL) return list2;
    if(list2==NULL) return list1;
    while(list1 !=NULL && list2 !=NULL){
        if(list1->val <= list2->val){
            mergelist->next = list1;
            list1=list1->next;
            mergelist=mergelist->next;
        }
        else{
            mergelist->next=list2;
            list2=list2->next;
            mergelist=mergelist->next;
        }
    }
    if(list1!=NULL) mergelist->next=list1;
    else mergelist->next=list2;
    return head.next;
}
```

## [15. 3Sum](https://leetcode.com/problems/3sum/description/?envType=study-plan-v2&envId=top-interview-150)
### 題目描述
給定一個整數陣列nums，回傳所有的triplets[nums[i],nums[j],nums[k]]，滿足i != j, i != k, and j != k，且nums[i ] + nums[j] + nums[k] == 0。
回傳不能有重複的triplets。
### 程式碼說明
- [ ] 程式碼雛形
宣告一個兩層vector ans，來存放回傳值。先把輸入的vector進行排序。用for迴圈去迭代，在每個迭代過程，把k設為迭代的counter加1，把j設為輸入字串的size減1。接著如果k<j，判斷如果nums[i]+nums[k]+nums[j]<0，則k++，nums[i]+nums[k]+nums[j]==0，代表這是一個正解，但是要存入ans之前，必須先查看ans裡面有沒有相同的值，若沒有則存入，k++ j--;其他情況的話j--。
最後將ans回傳。
```cpp
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-2;i++){
            int k=i+1,j=nums.size()-1;
            while(k<j){
                if(nums[i]+nums[k]+nums[j]<0){
                    k++;
                }
                else if(nums[i]+nums[k]+nums[j]==0){
                    vector<int> test = {nums[i], nums[k], nums[j]};
                    auto compare=find(ans.begin(),ans.end(),test);
                    if(compare==ans.end() ){
                        ans.push_back(test); 
                    }
                    k++;
                    j--;
                }
                else{
                    j--;
                }
            }
        }
        return ans;
    }
};
```

- [ ] 程式碼改善方法
上面的方法，當每次要存入一筆正解之前，都必須要判斷1次ans裡面是否有相同答案，這是相當耗時的作法。在這裡有一個改進方案，有一筆正解時，先不用判斷，直接存入ans裡面。for迴圈結束後，再將ans裡面重複資料刪除。
```cpp
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-2;i++){
            int k=i+1,j=nums.size()-1;
            while(k<j){
                if(nums[i]+nums[k]+nums[j]<0){
                    k++;
                }
                else if(nums[i]+nums[k]+nums[j]==0){
                    ans.push_back({nums[i], nums[k], nums[j]});
                    k++;
                    j--;
                }
                else{
                    j--;
                }
            }
        }
        set<vector<int>>uniqueans(ans.begin(),ans.end());
        ans.assign(uniqueans.begin(),uniqueans.end());
        return ans;
    }
};
```

## 面試過程檢討
### interviewer
- 出題方式可以有變化一點，不要讓interviewee馬上就能知道要寫出怎樣的程式。
- interviewer通常不會誇interviewee的approach。
- 可以在interviewee coding到一半時詢問interviewee。

### interviewee
- 在coding時，可以把念出程式碼，改成==說明這段程式碼的意義==。
- 在coding時，會發生程式碼打對，但是講出來的東西是錯的。 
    - 例如 ==`i<nums.size()-2`== 會講成 ==`i<nums.size()`==
- 可以放慢打字速度，==降低誤打率==。
- 在用英文說明程式碼時，沒辦法清楚表達。
- 在optimization的部分，可以先說明優化的想法在開始實作。
- 可以適當的使用==肢體動作==來輔助。
- 雖然在coding期間都有說明程式碼的用途，但是可以==善用註解來輔助==interviewer理解。

---

## 第二次作業-他評 01
### 關於 interviewer
- [ ] 優點
* [20:50](https://youtu.be/jJTtHZZQsy4?t=1250): 不會只提出一個問題點，一次提出兩個問題讓面試者去思考。

- [ ] 可改進的地方
* 講話太像照稿唸，雖然可能真的是在照稿唸，但可以有感情一點點。
* 題目可以換句話說，避免直接把想問的問題問出來，可以轉換成生活情境來問。

### 關於 interviewee
- [ ] 優點
* 打code流暢，邊講話邊打code不會卡詞。

- [ ] 可改進的地方
* 講中文時流暢但換成英文時速度明顯變慢了。
* [0:49](https://youtu.be/jJTtHZZQsy4?t=49): 通常面試應會在文字編輯器或是空白文件上打code，所以在開始打程式前應不會有打好任何程式在畫面上，也不會有自動縮排的功能。
* [10:51](https://youtu.be/jJTtHZZQsy4?t=651): 講話講到一半被卡掉了。
* [12:26](https://youtu.be/jJTtHZZQsy4?t=746): 在REACTO中，repeat,example和approach完皆沒有等面試人員給回覆就直接開始下面的流程，應留時間給面試人員提問。
* [21:35](https://youtu.be/jJTtHZZQsy4?t=1295): 盡量不要說"面試官" 。
* [30:35](https://youtu.be/jJTtHZZQsy4?t=1835): 打的code已經到螢幕的最下面了，應調整一下畫面讓面試人員可以看清楚完整的code。 

## 第二次作業-他評 02
### 關於 interviewer
- [ ] 優點
* 講話咬字很清楚
* [20:47](https://youtu.be/jJTtHZZQsy4?si=FdAvtMbBW05QSLLC&t=1247): 快速觀察interviewee剛完成的code，並點出不只一個問題協助interviewee思考優化方向

- [ ] 可改進的地方
* [10:53](https://youtu.be/jJTtHZZQsy4?si=SnzCDRmKKDCiWbiy&t=653): 比起直接問還有沒有其他作法，假設interviewer有其他的優化想法，可以用引導的方式問interviewee，也可以安排interviewee反問，增加互動
* [11:02](https://youtu.be/jJTtHZZQsy4?si=SrK9HIPXHE2w8Hyo&t=662): 這邊是不是沒剪好？才剛說進到下一題，後面又說直接進入第一題
* 題目可以先包裝過再提出，比較不容易被interviewee猜到

### 關於 interviewee
- [ ] 優點
* 一邊打code一邊說明不會卡，蠻流暢的
* 邏輯清晰，面對多種case的題目也可以逐一列出並完成對應的code
* 針對interviewer提出的點尋找優化的方向

- [ ] 可改進的地方
* 通常面試不會像LeetCode上面一樣一開始就把function跟輸入都寫好給你，應該要透過和interviewer互動來決定這些東西要如何設計
* [2:15](https://youtu.be/jJTtHZZQsy4?si=AotK4pzpo1OxVMKn&t=133): 這段在說明for迴圈的內容描述得不太清楚，也沒有說明j跟k分別代表什麼，這個部分應該是REACTO的A，建議捨棄掉實作的部分，專注在說明想法就好
* REACTO的T沒有做，針對前面舉的例子做測試會有助於讓interviewer理解運作方式
* REACTO的EAC的過程太快了，沒有跟interviewer互動
* (第三題)結束的太倉促




