Advertisement

Snapshot Array - LeetCode 1146 Solution

Snapshot Array - Complete Solution Guide

Snapshot Array is LeetCode problem 1146, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Implement a SnapshotArray that supports the following interface: SnapshotArray(int length) initializes an array-like data structure with the given length. Initially, each element equals 0 . void set(index, val) sets the element at the given index to be equal to val . int snap() takes a snapshot of the array and returns the snap_id : the total number of times we called snap() minus 1 . int get(index, snap_id) returns the value at the given index , at the time we took the snapshot with the given s

Detailed Explanation

The problem requires you to implement a `SnapshotArray` class that simulates taking snapshots of an array over time. The array is initialized with a given length and all elements are initially 0. The `set(index, val)` method allows you to update the value at a specific index. The `snap()` method takes a snapshot of the current array state and returns a unique `snap_id` (representing the snapshot number). Finally, the `get(index, snap_id)` method allows you to retrieve the value at a given index at a specific snapshot ID.

Solution Approach

The solution uses a list (or vector) of lists (or vectors). For each index in the array, we store a list of (snap_id, value) pairs. Whenever `set` is called, we append a new (snap_id, value) pair to the list at the given index, but only if the current snap_id is different from the last snap_id in the list. If it's the same snap_id, we overwrite the value. When `snap` is called, we simply increment a counter (`snap_id`) to keep track of the current snapshot number. When `get` is called, we perform a binary search on the list of snap IDs for the given index to find the most recent value set before or at the requested snap ID.

Step-by-Step Algorithm

  1. Step 1: Initialize the `SnapshotArray` with a given length. For each index in the array, create an empty list (or vector) to store (snap_id, value) pairs. Initialize the `snap_id` to 0.
  2. Step 2: When `set(index, val)` is called, retrieve the list of (snap_id, value) pairs for the given index.
  3. Step 3: Check if the current `snap_id` is the same as the last snap_id in the list. If it is, update the last value in the list. Otherwise, append a new (snap_id, value) pair to the list.
  4. Step 4: When `snap()` is called, increment the `snap_id` and return the previous `snap_id`.
  5. Step 5: When `get(index, snap_id)` is called, retrieve the list of (snap_id, value) pairs for the given index.
  6. Step 6: Perform a binary search on the list of snap IDs to find the largest snap ID that is less than or equal to the given `snap_id`.
  7. Step 7: Return the value corresponding to the found snap ID.

Key Insights

  • Insight 1: The core idea is to not store the entire array for each snapshot, as this would lead to excessive memory usage. Instead, we only store the changes (index and value) that occur between snapshots.
  • Insight 2: Using a list of (snap_id, value) pairs for each index allows efficient retrieval of values at specific snapshot IDs using binary search.
  • Insight 3: The binary search is crucial to achieve the O(log(snap_id)) time complexity for the `get` operation. We must find the latest snapshot ID (<= the target snap_id) for which a value was set at a specific index.

Complexity Analysis

Time Complexity: O(log(snap_id))

Space Complexity: O(length * snap_id)

Topics

This problem involves: Array, Hash Table, Binary Search, Design.

Companies

Asked at: Coupang, Databricks, Nvidia, Rubrik, Snowflake, StackAdapt, Verkada.