LeetCodeAnimation

repository·master·Indexed 13 days ago

https://github.com/misterbooo/leetcodeanimation

A project providing visual, animated explanations for LeetCode problems to help developers visualize pointer movements, state transitions, and recursion. It features reference implementations in Python, C++, and Java, and serves as a searchable, versioned index for the interactive animations hosted on algomooc.com.

Tokens
124.2K
Snippets
232
Records
278
Agent score
99%

What's inside LeetCodeAnimation

  1. Overview of LeetCodeAnimation

    master

    LeetCodeAnimation provides animated explanations for LeetCode problems, helping developers visualize pointer movements, state transitions, recursion expansion, and boundary conditions.

    Key Features:

    • Animated Solutions: Visualizes algorithms through GIFs or step-by-step animations.
    • Multi-language Support: Reference implementations are provided in Python (default), C++, and Java.
    • Interactive Web Version: While the GitHub repository serves as a public index and historical archive, the full interactive experience (step-by-step playback, variable speed, rewinding, and AI-synthesized voice explanations) is available on the official website.
  2. Design an Autocomplete System (LeetCode 642)

    master

    This document provides a solution and explanation for LeetCode problem #642: Design Search Autocomplete System. The goal is to build a system that returns the top 3 most frequent historical sentences that match a user's current input prefix.

    Requirements

    • Input: A sequence of characters (lowercase letters, spaces, or a special '#' character).
    • Ranking Rules:
      1. Sort by frequency (highest first).
      2. If frequencies are equal, sort by ASCII order (lexicographically smaller first).
      3. Return up to 3 sentences.
    • Termination: When '#' is input, the current sentence is saved to the history, and the system resets for a new search.

    API Interface

    • AutocompleteSystem(String[] sentences, int[] times): Constructor that initializes the system with historical sentence data and their respective frequencies.
    • List<String> input(char c): Processes the next character input. Returns the top 3 matching sentences or an empty list if no matches exist or if '#' is input.
  3. When to sync website changes to GitHub

    master

    Use the following logic to determine if a change on the website requires a synchronization to the GitHub repository:

    Change TypeSync to GitHub?Action
    New LeetCode animation added to study_index.jsYesSync manifest, index by number, index by topic, and sync records
    Modify problem number, slug, title, difficulty, or categoryYesSync manifest and indices; include problem number in commit
    Delete or offline an animationYesSync manifest and indices; leave a trace in sync records
    Fix index.html animation steps, copy, or stylesUsually NoCommit to website repo only; GitHub index remains unchanged
    Fix animation content and want a GitHub recordOptionalManually update docs/sync-log.md with a docs: log ... commit
    Add GitHub-side GIF, article, or code assetsYesSubmit assets; manifest automatically updates repoPath / gifPath
    Add new README preview GIFYesPlace in docs/assets/previews/ and update README (keep 4-6 selected cases)
  4. Dynamic Programming approach for Stone Game

    master

    For more complex variations of this game, use Dynamic Programming.

    Define dp(i, j) as the maximum score difference the current player can achieve from the subarray piles[i...j].

    • If it is the first player's turn: they want to maximize the score: max(piles[i] + dp(i+1, j), piles[j] + dp(i, j-1)).
    • If it is the second player's turn: they want to minimize the first player's score (or maximize their own): min(-piles[i] + dp(i+1, j), -piles[j] + dp(i, j-1)).

    This approach treats the game as a Directed Acyclic Graph (DAG) of states.

  5. Understand the bitCount algorithm (Population Count)

    master

    The bitCount algorithm counts the number of set bits in a 32-bit integer using a divide-and-conquer approach with bit manipulation masks. This method is highly efficient as it uses a fixed number of operations regardless of the input value.

    Step-by-Step Bit Counting Logic

    1. Count bits in pairs: Sum adjacent bits to get the count of 1s in every 2-bit group. i = i - ((i >>> 1) & 0x55555555)

    2. Count bits in nibbles (4-bit groups): Sum adjacent 2-bit groups. i = (i & 0x33333333) + ((i >>> 2) & 0x33333333)

    3. Count bits in bytes (8-bit groups): Sum adjacent 4-bit groups and mask to prevent overflow into adjacent groups. i = (i + (i >>> 4)) & 0x0f0f0f0f

    4. Count bits in 16-bit groups: Sum adjacent 8-bit groups. i = i + (i >>> 8)

    5. Count bits in 32-bit groups: Sum adjacent 16-bit groups. i = i + (i >>> 16)

    6. Final Mask: Extract the final count. Since a 32-bit integer can have at most 32 bits set, mask with 0x3f (binary 00111111) to clear unnecessary high bits. return i & 0x3f

    public static int bitCount(int i) {
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }
  6. Bit Manipulation Logic for Single Number II

    master

    To solve this problem in $O(1)$ space, you can use bit manipulation to simulate two sets:

    1. ones: Stores bits that have appeared exactly once.
    2. twos: Stores bits that have appeared exactly twice.

    When a bit appears for the third time, it should be removed from both ones and twos.

    Logic Flow

    • First appearance: Add to ones.
    • Second appearance: Remove from ones, add to twos.
    • Third appearance: Remove from twos.

    Bitwise Implementation

    To implement this, use the following updates in order:

    • one = (one ^ n) & (~two): Updates ones by XORing the new element n and masking out bits that are already in twos.
    • two = (two ^ n) & (~one): Updates twos by XORing the new element n and masking out bits that are now in ones.
  7. Concept: Floyd's Cycle Detection (Tortoise and Hare)

    master

    Floyd's Cycle Detection Algorithm is used to determine if a linked list (or any finite state machine/iterative function) contains a cycle and to find the cycle's starting point.

    Mathematical Logic

    Let $m$ be the distance from the head to the cycle entrance, and $n$ be the length of the cycle.

    When the slow pointer (tortoise) and fast pointer (hare) meet at point $M$ inside the cycle:

    • The slow pointer has traveled $x$ steps.
    • The fast pointer has traveled $f = 2x$ steps.
    • Since the fast pointer is in the cycle, it has completed $k$ full laps: $f = x + kn$.
    • Substituting $f = 2x$ gives $x = kn$.

    To find the entrance $P$: If we place one pointer at the head and keep the other at the meeting point $M$, and move both at the same speed (1 step at a time), they will meet exactly at the entrance $P$ after $m$ steps, because the distance from the head to the entrance is mathematically equivalent to the distance from the meeting point to the entrance (modulo cycle length).

  8. Implement AutocompleteSystem using a Trie

    master

    The recommended approach for this problem is using a Trie (Prefix Tree) combined with a Priority Queue.

    Implementation Strategy

    1. Data Structure: Use a Trie where each TrieNode stores the full string (str) and its frequency (cnt) if it represents the end of a sentence. Each node also contains a map of children nodes.
    2. State Tracking: Maintain a curNode pointer to track the current position in the Trie as the user types, and a stn string to build the current search prefix.
    3. Input Processing:
      • If c == '#': The current sentence is complete. Insert it into the Trie (incrementing its count), reset curNode to root, and clear the current string.
      • If c is a valid character:
        • Update curNode to the child node corresponding to c.
        • If the child doesn't exist, set curNode to NULL (no matches possible).
        • If it exists, perform a DFS (Depth First Search) starting from curNode to find all possible sentences in the subtree.
    4. Ranking: During DFS, collect all valid sentences into a Priority Queue (Max-Heap) configured with a custom comparator to handle the frequency and ASCII tie-breaking rules. Extract the top 3 elements from the queue for the result.
  9. Algorithm Logic for Intersection of Two Arrays II

    master

    The solution uses a frequency map approach to identify common elements:

    1. Frequency Mapping: Iterate through the first array (nums1) and use a map container to record the frequency of each element.
    2. Intersection Check: Iterate through the second array (nums2). For each element, check if it exists in the map with a frequency greater than 0.
    3. Result Construction: If a match is found, add the element to the result vector and decrement its frequency in the map to ensure correct counts for duplicate elements.
  10. Understand README statistics and automation

    master

    The numbers displayed in the README.md are managed by scripts and should not be edited manually.

    • Problem Count (e.g., 256): The number of LeetCode animation problems synchronized to this repository. This is calculated from the website's study_index.js and written to manifest.json and stats.json.
    • Site Total (e.g., 299): The total number of animations on the entire algomooc.com site (including advanced topics). This value is pulled from the site's content-stats and written to the siteTotal field in stats.json.

    Critical Rule: Do not manually type numbers between the <!-- LCA-AUTOGEN:STATS --> markers. Use node tools/scripts/build-readme.js --write to update them.

  11. Understand the difference between the GitHub repository and the website version

    master

    The GitHub repository serves as a public index and a historical archive of assets. However, it is a static copy. For the full interactive experience, you must use the website version at algomooc.com.

    Website-only features include:

    • Interactive Player: Step-through playback, replay, and speed control.
    • Voice Walkthroughs: AI-synthesized narration (Wu Shixiong's voice) available by clicking the 🔊 icon.
    • AI Tutor (Xiao Ou): An AI algorithm tutor to answer follow-up questions on ideas and edge cases.
    • Three-language code: Full access to Python, C++, and Java implementations (though the repo also contains these).
  12. How to apply Dynamic Programming

    master

    A problem is generally suitable for Dynamic Programming if it possesses these three properties:

    1. Optimal Substructure (最优化): The optimal solution to the problem contains optimal solutions to its subproblems.
    2. No Post-effect (无后效性): Once a state at a certain stage is determined, it is not affected by future decisions. The future depends only on the current state, not how the current state was reached.
    3. Overlapping Subproblems (重叠子问题): Subproblems are not independent; the same subproblem may be encountered multiple times during the calculation.

    Standard DP Workflow:

    1. Divide into stages: Partition the problem based on time or space characteristics.
    2. Define states and state variables: Describe the different conditions at each stage.
    3. Determine decisions and transition equations: Define how states evolve based on choices.
    4. Find boundary conditions: Establish the starting values (base cases) for the recursion/iteration.
    5. Implement the algorithm.