###### Agenda:
###### 10/05 10:00(UTC+8) 10/04 19:00(UTC-7)
###### 公布這次live session題目
###### 10/05 10:45(UTC+8) 10/04 19:45(UTC-7)
###### 開始逐步給hint
###### 10/05 11:30(UTC+8) 10/04 20:30(UTC-7)
###### 題解 + Q&A
###### 還沒有加入DC伺服器的請記得加入,並去查看#學員驗證頻道進行驗證才可以看到live session的討論區https://discord.gg/WUE3XutPK3
---
## 本周題目
## Leetcode weekly contest 324
## https://leetcode.com/contest/weekly-contest-324/
---
### Hint
- Q1 :
- hint 1: 如何判斷兩個字串similar
----
### Hint
- Q1
- hint 1: 如何判斷兩個字串similar
- hint 2: 去除重複的元素
----
### Hint
- Q1
- hint 1: 如何判斷兩個字串similar
- hint 2: 去除重複的元素
- hint 3: 讓剩下的元素的排列組合獨一無二
---
### Hint
- Q2:
- hint 1: 先不要考慮複雜度
----
### Hint
- Q2:
- hint 1: 先不要考慮複雜度
- hint 2: 如何判斷一個數字是質數
----
### Hint
- Q2:
- hint 1: 先不要考慮複雜度
- hint 2: 如何判斷一個數字是質數
- hint 3: 1不是質數,如果當下的數字是質數會發生什麼事
----
### Hint
- Q2:
- hint 1: 先不要考慮複雜度
- hint 2: 如何判斷一個數字是質數
- hint 3: 1不是質數,如果當下的數字是質數會發生什麼事
- hint 4: 做完操作後其實數字不會變大
---
### Hint
- Q3
- hint 1: degree代表每個點被幾個點連到,如何去計算degree呢
----
### Hint
- Q3
- hint 1: degree代表每個點被幾個點連到,如何去計算degree呢
- hint 2: Degree為奇數的點數只會有偶數個
----
### Hint
- Q3
- hint 1: degree代表每個點被幾個點連到,如何去計算degree呢
- hint 2: Degree為奇數的點數只會有偶數個
- hint 3: 每加一條邊會有兩個點的degree被影響
----
### Hint
- Q3
- hint 1: degree代表每個點被幾個點連到,如何去計算degree呢
- hint 2: Degree為奇數的點數只會有偶數個
- hint 3: 每加一條邊會有兩個點的degree被影響
- hint 4: 這題的case會需要分開討論,所以一個比較不乾淨的寫法是可以接受的
----
### Hint
- Q3
- hint 1: degree代表每個點被幾個點連到,如何去計算degree呢
- hint 2: Degree為奇數的點數只會有偶數個
- hint 3: 每加一條邊會有兩個點的degree被影響
- hint 4: 這題的case會需要分開討論,所以一個比較不乾淨的寫法是可以接受的
- hint 5: 若你想加一條邊但已經存在在graph上了,有沒有辦法多用多一點邊去達到一樣的效果
---
### Hint
- Q4
- hint 1: 每個點index/2會得到他的parent
----
### Hint
- Q4
- hint 1: 每個點index/2會得到他的parent
- hint 2: 一個數字x被除O(logx)次2後就會變成0
----
### Hint
- Q4
- hint 1: 每個點index/2會得到他的parent
- hint 2: 一個數字x被除O(logx)次2後就會變成0
- hint 3: 考慮每次詢問的兩個點都往同一個點走
----
### Hint
- Q4
- hint 1: 每個點index/2會得到他的parent
- hint 2: 一個數字x被除O(logx)次2後就會變成0
- hint 3: 考慮每次詢問的兩個點都往同一個點走
- hint 4: 紀錄一下走過的點
---
### 題解
----
### Q1
- 這題有很多種方法可以記錄,譬如說最多只有26個字母就開一個26大小的array紀錄
- 依序從a到z把有出現過的字母拿出來並串成一個字串
- 由於最多只有100個所以強制判斷一下就可以了
- 複雜度$O(n^2+\sum字串長度)$
----
### Q1 c++ code
```c++
int similarPairs(vector<string>& words) {
for(auto &it:words){
int cnt[26];
fill(cnt, cnt+26, 0);
for(char c:it) {
cnt[c-'a']=1;
}
it="";
for(int i = 0;i<26;i++){
if(cnt[i]) {
it = it + (char)('a'+i);
}
}
}
int ans=0;
for(int i= 0;i<words.size();i++){
for(int j = i+1;j<words.size();j++)ans+=(words[i]==words[j]);
}
return ans;
}
```
----
### Test case
- similar
- 兩個字串只是不同的排序
- "ab" and "ba"
- 兩個字串字母出現次數不同
- "aab" and "bba"
- non similar
----
### Follow up
能不能做的更快呢
$O(n+\sum字串長度)$
----
### Q2
- 當數字是質數的時候,只有他自己一個質因數
- 當數字不是質數的時候,每次做完題目所說的操作至少會變小接近一半
- 所以最多只會執行 $O(log n)$ 次操作
----
```c++
int smallestValue(int n) {
while(true) {
int tmp = n;
int sum = 0;
for(int i = 2 ; i * i <= tmp ; i++){
if(tmp % i == 0){
while(tmp % i == 0) {
tmp /= i;
sum += i;
}
}
}
if(tmp != 1) {
sum += tmp;
}
if(sum == n) {
return sum;
}
n=sum;
}
return 0;
}
```
----
### Test case
- 質數
- 2, 3, 5
- 合數
- 6, 10
- 答案會停在合數
- 4
----
### Q3
- 分成幾種case
- 所有點的 degree 皆為偶數
- return true
----
### Q3
- 分成幾種case
- 有兩個點的 degree 為奇數
- 若兩個點沒有邊
- return true
- 若兩個點有邊
- 去找一個額外點的點繞過去找得到的話就return true
- (1,2) -> (1,3) (3,2)
- 有四個點的 degree 為奇數
- 兩兩配對判斷有沒有邊
- 可以用Hash table之類的資料結構判斷有沒有邊
----
```c++
bool isPossible(int n, vector<vector<int>>& edges) {
vector<int> degree(n+1);
set<vector<int> > s;
for(auto it:edges){
degree[it[0]]++;
degree[it[1]]++;
s.insert(it);
swap(it[0], it[1]);
s.insert(it);
}
int cnt=0;
vector<int> v;
for(int i = 1;i <= n;i++){
if(degree[i] % 2 == 1) {
v.push_back(i);
}
}
if(v.empty()) {
return true;
}
if(v.size()==2){
if(s.find(vector<int>{v[0], v[1]}) == s.end()) {
return true;
}
for(int i = 1;i<=n;i++){
if(i != v[0] && i != v[1]){
if(s.find(vector<int>{v[0], i})==s.end()
&& s.find(vector<int>{v[1], i})==s.end()) {
return true;
}
}
}
return false;
}
if(v.size() == 4){
if(s.find(vector<int>{v[0], v[1]}) == s.end() && s.find(vector<int>{v[2], v[3]}) == s.end()) {
return true;
}
if(s.find(vector<int>{v[0], v[2]}) == s.end() && s.find(vector<int>{v[1], v[3]}) == s.end()) {
return true;
}
if(s.find(vector<int>{v[0], v[3]}) == s.end() && s.find(vector<int>{v[1], v[2]}) == s.end()) {
return true;
}
}
return false;
}
```
----
### Test case
- 全部degree都是偶數
- 有兩個點degree為奇數
- 兩個點沒有邊
- 兩個點有邊
- true -> n=3 (1,3)
- false -> n=4 (1,2)(2,3)(1,4)(4,3)(1,3)
- 有四個點degree為奇數
- 任兩點沒有邊
- 只有唯一一種組合可以成功
- false case
----
### Q4
- 每個詢問的兩個點同時往上走,直到遇到同一個人
- 因為往上會一直邊小,可以讓大的先走這樣保證他們會同時停在共同的parent上
- 中間經過的點數數量就是答案
----
```c++
vector<int> cycleLengthQueries(int n, vector<vector<int>>& queries) {
vector<int> res;
for(auto it:queries){
int ans = 1;
while(it[0] != it[1]) {
if(it[0] > it[1]) {
it[0] /= 2;
} else{
it[1] /= 2;
}
ans++;
}
res.push_back(ans);
}
return res;
}
```
----
### Test case
- 一般的case
- [4,7]
- 一個點為另一個點的parent的case
- [1,7]
{"title":"1005 live session","description":"Leetcode 1952 :","contributors":"[{\"id\":\"214a576a-9d94-453a-a11d-248251d46d4e\",\"add\":8763,\"del\":2488,\"latestUpdatedAt\":1759646794512}]"}