756. Pyramid Transition Matrix

更新 發佈閱讀 13 分鐘
https://leetcode.com/problems/pyramid-transition-matrix/submissions/1868719957

終於寫到一題有難度的 medium 了!!這一題若是沒有看過,光理解題目就要花點時間了。

理解題目後我第一時間想到的做法是 recursive:每一個 level 的 block 都去遍歷所有可能性的下一個 level 組合。看起來有點饒口,簡單來說就是每個 level 先找出所有上一層的可能性組合,這裡要透過 allowed 來做比對。找到後去一個一個的 recursive 繼續找,就是 DFS + DP 的做法。

想法很快就有了,但構建程式碼過程真的是很痛苦,畢竟 recursive 的程式碼本就容易寫錯。好不容易寫完後卻是有幾筆測資 TLE,才發現太多相似的 pattern 會被重複做 recursive,在我的做法裡這非常得耗時,因此我們需要適當的剪枝。我用的方式也沒啥特別的就是用 map,參考他的 input 規範,用 map 應該是還不會爆。

anyway 這一題 AC 真是困難重重,花了兩三個小時,最後拿到 beat 42% 的成績(memory 更是慘不忍睹這邊不提QQ)。感覺演算法的部分跟別人大差不差,之後再來看看別人都做了些啥。

class Solution {
public:
bool pyramidTransition(string bottom, vector<string>& allowed) {
map<string, string> allowedMap;
map<string, int> flagMap;
for (int i = 0; i < allowed.size(); i++) {
string temp = "";
temp.assign(allowed[i], 0, 2);
allowedMap[temp] += allowed[i][2];
}
return RecurStack(bottom, allowed, allowedMap, flagMap);
}

bool RecurStack(string bottom, vector<string>& allowed, map<string, string>& allowedMap, map<string, int>& flagMap){
if(bottom.length() == 2){

auto iter = flagMap.find(bottom);

if(iter != flagMap.end())
return false;

vector<string> allNextBottomVector;
allNextBottomVector = allNextBottomCombination(bottom, allowed, allowedMap);
if (allNextBottomVector.empty()) {
flagMap[bottom] = 0;
return false;
}
return true;
}
else {
vector<string> allNextBottomVector;
allNextBottomVector = allNextBottomCombination(bottom, allowed, allowedMap);
if (allNextBottomVector.empty()) return false;
for (auto bot: allNextBottomVector) {
auto iter = flagMap.find(bot);
if(iter != flagMap.end()) continue;
if (RecurStack(bot, allowed, allowedMap, flagMap) == true) return true;
flagMap[bot] = 0;
}
return false;
}
}

vector<string> allNextBottomCombination(string bottom, vector<string>& allowed, map<string, string>& allowedMap) {

vector<string> allNextBottomCombination;

string temp_str;
vector<string> temp_vec;
temp_vec.push_back("");
for (int i = 0; i < bottom.length() - 1; i++) {
temp_str = "";
temp_str.assign(bottom, i, 2);
auto iter = allowedMap.find(temp_str);
if(iter != allowedMap.end()) {
for (int j = 0; j < iter->second.length(); j++) {
for (int k = 0; k < temp_vec.size(); k++) {
if (allNextBottomCombination.size() < k + j * temp_vec.size() + 1) {
allNextBottomCombination.push_back("");
}
allNextBottomCombination[k + j * temp_vec.size()] = temp_vec[k] + iter->second[j];
}
}
temp_vec = allNextBottomCombination;
}

else {
vector<string> dummy;
return dummy;
}
}
return allNextBottomCombination;
}
};

Best Solution

不想看解釋的可以直接讀 code,個人認為可讀性很高(自己說)

總而言之結合了討論區還有 gmeini 的建議,我把程式碼改寫成了如下。主要有兩個優化的地方:

第一個是改用 bitset。上過程式基礎課程的人一定都知道用 bit 的操作會遠遠大於用其他的資料型態,但偏偏 bit 的使用不那麼直覺。看了別人的寫法猶如醍醐灌頂,原來這就是刷題的真諦。

第二個是改用徹底的 DFS。原本的做法其實有點四不像,雖然有 DFS 的影子,卻還要用大量的時間去 search 下一步的所有可能性。這點很可惜,因為我到最後都在思考要如何優化這邊,可惜試了一下還是放棄思考了直接看解答。

class Solution {

int patterns[6][6];
unordered_set<string> failed;

public:
bool pyramidTransition(string bottom, vector<string>& allowed) {

memset(patterns, 0, sizeof(patterns));
failed.clear();
for (const string& s : allowed) {
patterns[s[0] - 'A'][s[1] - 'A'] |= (1 << (s[2] - 'A'));
}

return solve(bottom, "");
}

bool solve(string& bottom, string next) {

if (bottom.length() == 1)
return true;

if (next.length() == bottom.length() - 1) {
if (failed.count(next))
return false;

if (solve(next, ""))
return true;
failed.insert(next);
return false;
}

int left = bottom[next.length()] - 'A';
int right = bottom[next.length() + 1] - 'A';
int mask = patterns[left][right];

for (int i = 0; i < 6; ++i) {
if (mask & (1 << i)) {
if (solve(bottom, next + (char)('A' + i))) {
return true;
}
}
}

return false;
}
};

刷了四題下來唯一我有去看討論區的,目前感想是 leetcode 很多這種好題目(燒腦),但也很多跟標示難度不一的題目。除此之外也是把一些平常沒在用的優化技巧撿回來(像是這次的 bitset)。已經很久沒有過這種每一個計算都要斤斤計較的程式撰寫過程了,大學後期我修到的課基本上只在乎有沒有做出來的結果論,不在乎效能那些。因為當時想逃避這種天才怪物最多的課程哈哈哈,在 leetcode 終究還是要還(笑著說)。

留言
avatar-img
星星在晚上的時候不睡覺
0會員
13內容數
資工系的勞碌人生
2025/12/28
https://leetcode.com/problems/add-two-numbers?envType=problem-list-v2&envId=rabvlt31 很簡單的一題,不知道為啥加在 Medium。 簡單來說,就是每個位數的相加,沒有難度,題目甚至已經是 reverse 的 li
2025/12/28
https://leetcode.com/problems/add-two-numbers?envType=problem-list-v2&envId=rabvlt31 很簡單的一題,不知道為啥加在 Medium。 簡單來說,就是每個位數的相加,沒有難度,題目甚至已經是 reverse 的 li
2025/12/28
https://leetcode.com/problems/count-negative-numbers-in-a-sorted-matrix 簡單題目,有 Sorted 根本天使。續 88. 的概念,在 decreasing in row-wise and col-wise 的情況下,左上的數字
2025/12/28
https://leetcode.com/problems/count-negative-numbers-in-a-sorted-matrix 簡單題目,有 Sorted 根本天使。續 88. 的概念,在 decreasing in row-wise and col-wise 的情況下,左上的數字
2025/12/28
https://leetcode.com/problems/merge-sorted-array 這是一個很經典也很簡單的題目,目的是要將兩個已經排序好的陣列合成一個排序好的大陣列。 題目描述中有說到這是兩個 non-decreasing 的陣列,也就是 non-strictly increas
2025/12/28
https://leetcode.com/problems/merge-sorted-array 這是一個很經典也很簡單的題目,目的是要將兩個已經排序好的陣列合成一個排序好的大陣列。 題目描述中有說到這是兩個 non-decreasing 的陣列,也就是 non-strictly increas
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
市場經驗拉長之後,很多投資人都會遇到同一個問題:不是方向看錯,而是部位太集中個股,常常跟大趨勢脫節。 早年的台股環境,中小股非常吃香,反而權值股不動,但QE量化寬鬆後,特別是疫情之後,後疫情時代,鈔票大量在股市走動,這些大資金只能往權值股走,因此早年小P的策略偏向中小型個股,但近年AI興起,高技術
Thumbnail
市場經驗拉長之後,很多投資人都會遇到同一個問題:不是方向看錯,而是部位太集中個股,常常跟大趨勢脫節。 早年的台股環境,中小股非常吃香,反而權值股不動,但QE量化寬鬆後,特別是疫情之後,後疫情時代,鈔票大量在股市走動,這些大資金只能往權值股走,因此早年小P的策略偏向中小型個股,但近年AI興起,高技術
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
從CS 1.6到現代電競遊戲,本文追溯電競耳機25年來的進化史,涵蓋不同時期的代表性產品,並探討技術變革與玩家需求的演變。
Thumbnail
從CS 1.6到現代電競遊戲,本文追溯電競耳機25年來的進化史,涵蓋不同時期的代表性產品,並探討技術變革與玩家需求的演變。
Thumbnail
當我們身心健康、家庭美滿、事業有成、事主有力的時候,在講台上見證,侃侃而談「即或不然」(但三18)、「應允與否兩皆可」是容易的 ,但這看來不是大部分人或人生大部分時候的經驗。
Thumbnail
當我們身心健康、家庭美滿、事業有成、事主有力的時候,在講台上見證,侃侃而談「即或不然」(但三18)、「應允與否兩皆可」是容易的 ,但這看來不是大部分人或人生大部分時候的經驗。
Thumbnail
 2024年9月,越南Dong Tam集團跟CS Wind簽署合作協議,預計在胡志明市旁的隆安省芹勺縣工業園區興建新廠,投資金額上看2千萬美金,用於建造工廠,生產陸域、離岸風機塔架,還有其他部件如水下基礎的單樁、轉接段等。
Thumbnail
 2024年9月,越南Dong Tam集團跟CS Wind簽署合作協議,預計在胡志明市旁的隆安省芹勺縣工業園區興建新廠,投資金額上看2千萬美金,用於建造工廠,生產陸域、離岸風機塔架,還有其他部件如水下基礎的單樁、轉接段等。
Thumbnail
經過這兩天滿滿的bo3,通往傳奇組的門票只剩下三張了,而剩下的隊伍不是黑馬就是傳統豪門。
Thumbnail
經過這兩天滿滿的bo3,通往傳奇組的門票只剩下三張了,而剩下的隊伍不是黑馬就是傳統豪門。
Thumbnail
MAJOR挑戰者組進行到第二天,由於本次賽制,只要攸關晉級或是淘汰的比賽都需要打BO3,在昨日經過四場BO3以及四場BO1,整個態勢已逐漸明朗。還是一如往常的CS:GO,黑馬、滑鐵盧等劇情不斷上演。
Thumbnail
MAJOR挑戰者組進行到第二天,由於本次賽制,只要攸關晉級或是淘汰的比賽都需要打BO3,在昨日經過四場BO3以及四場BO1,整個態勢已逐漸明朗。還是一如往常的CS:GO,黑馬、滑鐵盧等劇情不斷上演。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News