---
title: 2022 年「資訊科技產業專案設計」第 1 次作業
tags: 資訊科技產業專案設計
---
# 2022 年「[資訊科技產業專案設計](https://hackmd.io/@sysprog/info2022/https%3A%2F%2Fhackmd.io%2F%40sysprog%2FBJLSJ3ggi)」第 1 次作業
> 貢獻者:瓈文琳 Lorian
>[影片(漢)](https://youtu.be/avhZwrz0pP8) 、[video(EN)](https://youtu.be/_8tvuVsV-ys)
😎:interviewer 🤔:interviewee
## [REACTO](https://www.youtube.com/watch?v=DIR_rxusO8Q&t=5s)
* Repeat:
重複提問,確認自己理解原本的要求
* Examples:
針對題目條件,舉出符合的案例,不限於特例
可以舉例input跟output,確認有沒有理解正確
* Approach:
說明自己打算採用的方案
講述自己的邏輯,用哪種approach
* Code:
撰寫程式,展現自己寫的東西的confidence level
可以寫pseudo code,他們想看到的是你的邏輯、你的想法
* Test:
若不能實際測試,那說明驗證程式的方案
可以用別的顏色的筆將例子自己跑一遍看最後跑出來的結果對不對
* Optimization:
對於大量資料的表現如何 Big O等等
* keep talking 就算不會也不要卡在那裏
## [66. Plus One](https://leetcode.com/problems/plus-one/)(漢1)
😎:瓈文琳同學你好,歡迎來面試,面試總共有兩題,等等請你先開啟給你的google文件,有分題號,希望你在上面作答。
🤔:你好,好的,我打開了。
😎:好的,第一題,給你一個很大的整數,以array的形式表示,陣列由左至右為最高有效位到最低有效位,將這個數字加上1之後回傳陣列答案。
🤔:好,所以這題是給一個用陣列表示的整數,希望回傳一個加1後的整數。如果input是[1,2,3,4]的話,加一會是[1,2,3,5]沒錯嗎?
😎:沒錯。
🤔:那想問一下如果遇到進位的情況,像是[9,9,9,9],回傳會是[1,0,0,0,0]嗎?
😎:對。
🤔:好,那我想我會需要先得到這個陣列的大小,並從最後一個數字開始加上1,如果等於10的話表示這裡要放0,並且設定carry bit 為1,接著往前跑for迴圈將整個陣列跑過一遍加上carry bit,若是跑完還有carry bit沒加完的話,最後要在整個陣列前面insert 1。
### for迴圈每位跑加法
```cpp
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n = digits.size();
int carry = 0;
if(digits[n-1] + carry + 1 >= 10){
digits[n-1] = (digits[n-1] + carry + 1) % 10;
carry = 1;
}else{
digits[n-1] = digits[n-1] + carry + 1;
carry = 0;
}
for(int i = n-2;i >= 0;i--){
if(digits[i] + carry >= 10){
digits[i] = (digits[i] + carry) % 10;
carry = 1;
}else{
digits[i] = digits[i] + carry;
carry = 0;
}
}
if(carry == 1){
digits.insert(digits.begin(),1);
}
return digits;
}
};
```
😎:這個作法是沒有問題,那你知道這樣的時間複雜度嗎?
🤔:因為每個數字都跑一遍所以是O(n)。
😎:下界呢?
🤔:是Ω(n)。
😎:有沒有可以讓下界變小的方法?
🤔:我想可以設定一些即時停止的條件,像是如果個位數字沒有大於10就可以回傳了。
### 及時停止
```cpp
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int i = digits.size()-1;
digits[i] += 1;
while(i >= 0) {
if (digits[i] != 10) return digits;
digits[i] = 0;
if (i > 0) digits[i - 1] += 1;
else digits.insert(digits.begin(), 1);
i--;
}
return digits;
}
};
```
## [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/)(漢2)
😎:好的那現在是第二題,給你一個字串,找到長度最大的子字串,而這個子字串不可以有重複的字元
🤔:好,所以我現在會有一個字串s,然後我要找到裡面最長的子字串,其中那些字串不可以有重複的字元,然後要回傳字串的長度
🤔:假設s是abcdas,最長的子字串就是bcdas,所以要回傳5。
🤔:那我覺得可以用iterator跑一遍字串,記錄下目前子字串的字母,所以跑到a的時候會發現有重複,紀錄現在的長度,記錄下現在最大的值,然後繼續往後面做
😎:你說的繼續往下做是指直接從遇到重複的後面開始做嗎?
🤔:噢不是,當遇到重複時,會先記錄下目前子字串的開頭跟結尾,所以當重複時,應該要從上一次子字串的開頭下一個開始檢查
### iterator 逐步比對
```cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
string curr = "";
int max = 0;
int n = 0;
string::iterator start = s.begin();
for (string::iterator it=s.begin(); it!=s.end(); ++it){
string::size_type idx = curr.find(*it);
if(idx != string::npos){
n = curr.size();
if(n > max){
max = n;
}
++start;
it = start;
curr = *it;
}else{
curr = curr + *it;
}
}
n = curr.size();
if(n > max){
max = n;
}
return max;
}
};
```
😎:但這樣似乎會重複檢查很多次,有更快的做法嗎?
🤔:我想可以記錄一下每個字元在字串中的所在位置和字串的左界右界,遇到重複時應該要從他的重複字元的下一個,或是目前最左界的位置開始
🤔:因為有可能遇到abcdbas的情況,檢查到第二次的a時就不可以再從第一個a的下一個開始檢查,這個時候左界已經因為前面重複b時跑到c的位子了
### Sliding Window Optimized
```cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = int(s.length());
int Max = 0;
unordered_map<char, int> mp;
for (int r = 0, l = 0; r < n; r++){
if(mp[s[r]] > 0) {
l = max(l,mp[s[r]]);
}
mp[s[r]] = r + 1;
Max = max(Max, r - l + 1);
}
return Max;
}
};
```
## 漢語影片檢討
* interviewee:
* 第一題說給一個「很大」的整數,卻沒有講清楚到底多大
* 題目的限制應該都要再講更清楚一點
* 互動有點偏少,應該再多問點問題才能了解面試者
* 比較被動,應更掌握面試主導權
* 用了「似乎」的說法,讓人感覺沒很專業
* interviewer:
* 提問者沒有講題目限制,應主動發問多了解題目
* 回答時會有點冗言贅字,或有時候講話有點繞(筆記上有用比較通順的寫法沒有完全照口語打)
* 測試時間有點冗長與卡頓,第一題最主要的digits應該一開始就列在旁邊並更新變動,比較清楚表示。不過有檢查出程式碼沒寫好的地方還不錯。
* 第二題可以直接說用sliding window就好,一下有講左界右界一下沒講會有點聽不懂
## [67. Add Binary](https://leetcode.com/problems/add-binary/)(英)
😎:Hello Lorian, welcome to the interview. Please open the google doc for the question.
🤔:Hello. Okay, I have opened it.
😎:Okay. The question for you is that you will be given two binary strings a and b, and you have to return a binary string of their sum.
😎:If a is 11 and b is 1, then return 100.
😎:a and b will always be 0 or 1. and the length of these strings will be shorter than 105.
🤔:Okay I got it. I think I have to add two strings that represent binary numbers together and return the sum of them.
🤔:So if I get 101 and 11, I have to return 1000.
😎:Right.
🤔:Okay. I think I should first get the length of the strings and add them from the end of the two strings with a carry bit.
🤔:If the sum of the three numbers is bigger than 1, then the next carry bit is 1.
🤔:I also have to divide 2 by sum, and add the remainder of sum to the beginning of the answer.
😎:So how do you add the string together like an integer?
🤔:I think the character minus 0 as a character, like this(c - ‘0’),will make the character to be an integer. Then I can use it to do the calculation.
```cpp
class Solution {
public:
string addBinary(string a, string b){
int i = a.length() - 1;
int j = b.length() - 1;
string ans;
int carry = 0;
while(i>=0 || j>=0 || carry){
int sum = carry;
if(i>=0) sum += (a[i--] - '0');
if(j>=0) sum += (b[j--] - '0');
if(sum>1) carry = 1;
else carry = 0;
ans = to_string(sum%2) + ans;
}
//if(carry) ans = to_string(carry) +ans;
return ans;
}
};
```
## 英語影片檢討
* interviewee:
* 英文發音有怪的地方,例如最後的That's it就沒講好
* 和面試者的互動可以再多一點
* 最後提點修改的地方有點太直接
* interviewer:
* 沒有提到複雜度、空間相關問題,可以自己提一下
* 有些英文發音或用法有點怪怪的可以再修正,例如OK I'm done就是一個很怪的用法,應該是要說I have done.