Leetcode: 753. Cracking the Safe

Problem Statement

class Solution:
    def crackSafe(self, n: int, k: int) -> str:
        M = k**n
        ans = None

        def bt(cur, words):
            nonlocal ans
            if len(words) == M:
                ans = cur
                return
            if ans is not None:
                return
            for d in range(k):
                new = cur + str(d)
                word = new[-n:]
                if word not in words:
                    if len(word) == n:
                        words.add(word)
                    bt(new, words)
                    if len(word) == n:
                        words.discard(word)

        bt("", set())
        return ans


assert Solution().crackSafe(1, 2) == "10"
assert Solution().crackSafe(2, 2) == "01100"
class Solution:
    def crackSafe(self, n: int, k: int) -> str:
        st = ["0" * n]
        seen = set(st)

        def adj(u):
            for i in range(k):
                v = (u + str(i))[-n:]
                if v not in seen:
                    return v
            return None

        words = []
        while st:
            u = adj(st[-1])
            if u is None:
                words.append(st.pop())
                continue
            seen.add(u)
            st.append(u)
        words.reverse()

        res = words[0]
        for w in words[1:]:
            res += w[-1]
        return res


assert Solution().crackSafe(1, 2) == "10"
assert Solution().crackSafe(2, 2) == "01100"