Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Cat and Mouse

Updated
4 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "913" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. The graph is given as follows: graph[a] is a list of all nodes b such that ab is an edge of the graph. The mouse starts at node 1 and goes first, the cat starts at node 2 and goes second, and there is a hole at node 0. During each player's turn, they must travel along one edge of the graph that meets where they are. For example, if the Mouse is at node 1, it must travel to any node in graph[1]. Additionally, it is not allowed for the Cat to travel to the Hole (node 0). Then, the game can end in three ways: If ever the Cat occupies the same node as the Mouse, the Cat wins. If ever the Mouse reaches the Hole, the Mouse wins. If ever a position is repeated (i.e., the players are in the same position as a previous turn, and it is the same player's turn to move), the game is a draw. Given a graph, and assuming both players play optimally, return 1 if the mouse wins the game, 2 if the cat wins the game, or 0 if the game is a draw. Example 1: Input: graph = [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]] Output: 0 Example 2: Input: graph = [[1,3],[0],[3],[0,2]] Output: 1 Constraints: 3 <= graph.length <= 50 1 <= graph[i].length < graph.length 0 <= graph[i][j] < graph.length graph[i][j] != i graph[i] is unique. The mouse and the cat can always move.

Explanation

Here's the breakdown of the solution:

  • Minimax with Memoization: The core idea is to use minimax to explore the game tree, where the mouse tries to minimize the cat's chances of winning, and the cat tries to maximize its chances of winning. Memoization (dynamic programming) is crucial to avoid recomputing results for previously visited game states, which drastically reduces runtime.
  • State Representation: The state of the game is represented by (mouse_position, cat_position, turns_remaining). The turns_remaining limits the depth of the search and helps identify draw states (repeated positions with the same player's turn).
  • Optimal Play: The minimax algorithm recursively explores possible moves for both players, assuming they play optimally. The base cases are when the mouse reaches the hole (mouse wins), the cat catches the mouse (cat wins), or the maximum number of turns is reached (draw).

  • Time Complexity: O(N^2 T), where N is the number of nodes in the graph and T is the maximum number of turns (typically a constant like 2 N).

  • Space Complexity: O(N^2 * T) due to memoization.

Code

    def catMouseGame(graph):
    n = len(graph)
    DRAW = 0
    MOUSE_WINS = 1
    CAT_WINS = 2
    turns = 2 * n  # Maximum turns before declaring a draw

    memo = {}  # Memoization table: (mouse, cat, turn) -> result

    def get_result(mouse, cat, turn):
        if (mouse, cat, turn) in memo:
            return memo[(mouse, cat, turn)]

        if turn == turns:
            memo[(mouse, cat, turn)] = DRAW
            return DRAW

        if mouse == 0:
            memo[(mouse, cat, turn)] = MOUSE_WINS
            return MOUSE_WINS

        if mouse == cat:
            memo[(mouse, cat, turn)] = CAT_WINS
            return CAT_WINS

        if turn % 2 == 0:  # Mouse's turn
            result = CAT_WINS  # Optimistically assume cat wins
            for next_mouse in graph[mouse]:
                next_result = get_result(next_mouse, cat, turn + 1)
                if next_result == MOUSE_WINS:
                    memo[(mouse, cat, turn)] = MOUSE_WINS
                    return MOUSE_WINS  # Mouse can force a win
                elif next_result == DRAW:
                    result = DRAW  # Mouse can at least force a draw
            memo[(mouse, cat, turn)] = result
            return result
        else:  # Cat's turn
            result = MOUSE_WINS  # Optimistically assume mouse wins
            for next_cat in graph[cat]:
                if next_cat != 0:  # Cat cannot move to the hole
                    next_result = get_result(mouse, next_cat, turn + 1)
                    if next_result == CAT_WINS:
                        memo[(mouse, cat, turn)] = CAT_WINS
                        return CAT_WINS  # Cat can force a win
                    elif next_result == DRAW:
                        result = DRAW  # Cat can at least force a draw
            memo[(mouse, cat, turn)] = result
            return result

    return get_result(1, 2, 0)

More from this blog

C

Chatmagic blog

2894 posts