---
# System prepended metadata

title: 'LeetCode #752 [Open the Lock](https://leetcode.com/problems/open-the-lock/)'
tags: [LeetCode, Medium, BFS, Queue]

---

###### 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;
    }
};
```