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
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
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,通往傳奇組的門票只剩下三張了,而剩下的隊伍不是黑馬就是傳統豪門。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News