All Downloads are FREE. Search and download functionalities are using the official Maven repository.

g0701_0800.s0752_open_the_lock.Solution Maven / Gradle / Ivy

There is a newer version: 1.38
Show newest version
package g0701_0800.s0752_open_the_lock;

// #Medium #Array #String #Hash_Table #Breadth_First_Search
// #Graph_Theory_I_Day_12_Breadth_First_Search
// #2022_03_25_Time_72_ms_(91.06%)_Space_69.8_MB_(69.73%)

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

/**
 * 752 - Open the Lock\.
 *
 * Medium
 *
 * You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: `'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'`. The wheels can rotate freely and wrap around: for example we can turn `'9'` to be `'0'`, or `'0'` to be `'9'`. Each move consists of turning one wheel one slot.
 *
 * The lock initially starts at `'0000'`, a string representing the state of the 4 wheels.
 *
 * You are given a list of `deadends` dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.
 *
 * Given a `target` representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.
 *
 * **Example 1:**
 *
 * **Input:** deadends = ["0201","0101","0102","1212","2002"], target = "0202"
 *
 * **Output:** 6
 *
 * **Explanation:** 
 *
 * A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202". 
 *
 * Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid, 
 *
 * because the wheels of the lock become stuck after the display becomes the dead end "0102".
 *
 * **Example 2:**
 *
 * **Input:** deadends = ["8888"], target = "0009"
 *
 * **Output:** 1
 *
 * **Explanation:** We can turn the last wheel in reverse to move from "0000" -> "0009".
 *
 * **Example 3:**
 *
 * **Input:** deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
 *
 * **Output:** -1
 *
 * **Explanation:** We cannot reach the target without getting stuck.
 *
 * **Constraints:**
 *
 * *   `1 <= deadends.length <= 500`
 * *   `deadends[i].length == 4`
 * *   `target.length == 4`
 * *   target **will not be** in the list `deadends`.
 * *   `target` and `deadends[i]` consist of digits only.
**/
public class Solution {
    public int openLock(String[] deadEnds, String target) {
        Set visited = new HashSet<>();
        for (String end : deadEnds) {
            visited.add(Integer.parseInt(end));
        }
        if (visited.contains(0)) {
            return -1;
        }
        Queue queue = new LinkedList<>();
        queue.add(new int[] {0, 0});
        visited.add(0);
        int numTarget = Integer.parseInt(target);
        while (!queue.isEmpty()) {
            int[] node = queue.poll();
            int number = node[0];
            int dist = node[1];
            if (number == numTarget) {
                return dist;
            }
            int[] neighbors = getNeighbors(number);
            for (int neighbor : neighbors) {
                if (visited.contains(neighbor)) {
                    continue;
                }
                visited.add(neighbor);
                queue.add(new int[] {neighbor, dist + 1});
            }
        }
        return -1;
    }

    private int[] getNeighbors(int number) {
        int[] neighbors = new int[8];
        int index = 0;
        int ten = 10;
        for (int i = 1; i <= 4; i++) {
            neighbors[index++] = (number / ten) * ten + (number + ten / 10) % ten;
            neighbors[index++] = (number / ten) * ten + (number + 9 * (ten / 10)) % ten;
            ten *= 10;
        }
        return neighbors;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy