###### tags: `LeetCode` `BFS` `Queue` `Medium` # LeetCode #752 [Open the Lock](https://leetcode.com/problems/open-the-lock/) ### (Medium) 你有一個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' 。每個撥輪可以自由旋轉:例如把 '9' 變為 '0','0' 變為 '9' 。每次旋轉都只能旋轉一個撥輪的一位數字。 鎖的初始數字為 '0000' ,一個代表四個撥輪的數字的字符串。 列表 deadends 包含了數組死亡數字,一旦撥輪的數字和列表裡的任何一個元素相同,這個鎖將會被永久鎖定,無法再被旋轉。 字符串 target 代表可以解鎖的數字,你需要給出解鎖需要的最小旋轉次數,如果無論如何不能解鎖,返回 -1 。 --- 首先, 若"0000"在deadends中, 則回傳-1。 使用BFS遍歷從"0000"開始的每一動情況, 並使用unordered_set<int> visited紀錄, 省去重複時間。每一數字鎖皆可往前或往後撥動一次(+1或-1)。 使用queue進行BFS, 當佇列中的數字組合等於目標數時, 回傳步數。 --- ``` class Solution { public: int openLock(vector<string>& deadends, string target) { queue<string> q; int steps = 0; unordered_set<string> set_(deadends.begin(), deadends.end()); unordered_set<string> visited; if(set_.count("0000"))return -1; string test(target); q.push("0000"); int locksize=4; while(!q.empty()){ for(int i = q.size();i>0;i--){ string s = q.front();q.pop(); if(s==target)return steps; for(int j=0;j<locksize;j++){ const char c = s[j]; s[j] = c=='9'?'0':c+1; if(!set_.count(s)&&!visited.count(s)){ q.push(s); visited.insert(s); } s[j] = c=='0'?'9':c-1; if(!set_.count(s)&&!visited.count(s)){ q.push(s); visited.insert(s); } s[j]=c; } } steps++; } return -1; } }; ```