1. 程式人生 > 其它 >LeetCode752. 開啟轉盤鎖

LeetCode752. 開啟轉盤鎖

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之中
  • targetdeadends[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; } }