LeetCode752. 開啟轉盤鎖
阿新 • • 發佈:2021-06-25
752. 開啟轉盤鎖
你有一個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字:'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
。每個撥輪可以自由旋轉:例如把'9'
變為'0'
,'0'
變為'9'
。每次旋轉都只能旋轉一個撥輪的一位數字。
鎖的初始數字為'0000'
,一個代表四個撥輪的數字的字串。
列表deadends
包含了一組死亡數字,一旦撥輪的數字和列表裡的任何一個元素相同,這個鎖將會被永久鎖定,無法再被旋轉。
字串target
代表可以解鎖的數字,你需要給出解鎖需要的最小旋轉次數,如果無論如何不能解鎖,返回-1
。
示例 1:
輸入:deadends = ["0201","0101","0102","1212","2002"], target = "0202" 輸出:6 解釋: 可能的移動序列為 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。 注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 這樣的序列是不能解鎖的, 因為當撥動到 "0102" 時這個鎖就會被鎖定。
示例 2:
輸入: deadends = ["8888"], target = "0009" 輸出:1 解釋: 把最後一位反向旋轉一次即可 "0000" -> "0009"。
示例 3:
輸入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" 輸出:-1 解釋: 無法旋轉到目標數字且不被鎖定。
示例 4:
輸入: deadends = ["0000"], target = "8888" 輸出:-1
提示:
1 <=deadends.length <= 500
deadends[i].length == 4
target.length == 4
target
不在deadends
之中target
和deadends[i]
僅由若干位數字組成
思路1:bfs
此問題可以轉化為求源到目的的最小路徑長度問題,採用bfs可做。
1.狀態的轉移:一個字串每次只能撥動一位,因此相鄰的轉換狀態為字串中每個字元向上或向下撥動一次
如:0000 -> 0001, 0010, 0009...
2. 需要記錄每個轉換狀態,避免同一狀態重複進入佇列
3. 每次需要對每個轉換狀態,判斷是否在deadends
具體程式碼
class Solution { public int openLock(String[] deadends, String target) {if ("0000".equals(target)) return 0; Set<String> deadSet = new HashSet<>(); for (String deadend: deadends) deadSet.add(deadend); if (deadSet.contains("0000")) { return -1; } Queue<String> q = new LinkedList<>(); q.offer("0000"); Set<String> seen = new HashSet<>(); seen.add("0000"); int step = 0; while (!q.isEmpty()) { ++step; int size = q.size(); for (int i=0; i<size; i++) { String status = q.poll(); for (String nextStatus: get(status)) { if (!seen.contains(nextStatus) && !deadSet.contains(nextStatus)) { if (nextStatus.equals(target)) { return step; } q.offer(nextStatus); seen.add(nextStatus); } } } } return -1; } private Character numPre(char ch) { return ch == '0'? '9': (char)(ch - 1); } private Character numSucc(char ch) { return ch == '9'? '0': (char)(ch + 1); } private List<String> get(String status) { List<String> tmp = new ArrayList<>(); char[] chs = status.toCharArray(); for (int i=0; i<4; i++) { char num = chs[i]; char pre = numPre(num); chs[i] = pre; tmp.add(new String(chs)); char succ = numSucc(num); chs[i] = succ; tmp.add(new String(chs)); chs[i] = num; } return tmp; } }