BackmediumHashinguncategorizedmedium

Generate Unique Book Codes Solution

Problem Statement

Given a list of books, each represented as a tuple of title, author, and publication year, generate a list of unique identifiers. The identifiers should be based on the book's information and ensure that no two books have the same identifier.

Example 1
Input
[['Book1', 'Author1', 2020], ['Book2', 'Author2', 2021]]
Output
["Book1_Author1_2020","Book2_Author2_2021"]

Explanation: Step 1: Create a list of unique identifiers by combining the title, author, and publication year of each book. For the first book, we combine 'Book1', 'Author1', and '2020' to get 'Book1_Author1_2020'. For the second book, we combine 'Book2', 'Author2', and '2021' to get 'Book2_Author2_2021'.

Example 2
Input
[['Book3', 'Author3', 2022], ['Book3', 'Author3', 2022]]
Output
["Book3_Author3_2022","Book3_Author3_2022"]

Explanation: Step 1: Create a list of unique identifiers by combining the title, author, and publication year of each book. For the first book, we combine 'Book3', 'Author3', and '2022' to get 'Book3_Author3_2022'. For the second book, we combine 'Book3', 'Author3', and '2022' to get 'Book3_Author3_2022'. Note that the output is not unique, as the function does not handle the case when two books have the same title, author, and publication year.

Constraints

  • 1 <= number of books <= 1000
  • 1 <= length of title <= 50
  • 1 <= length of author <= 50
  • 1900 <= publication year <= 2100
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Generate Unique Book Codes — Problem Statement & Solution Guide

HashingMediumMixed
TimeO(N * L)
|
SpaceO(N)

Problem Description

Given a list of books, each represented as a tuple of title, author, and publication year, generate a list of unique identifiers. The identifiers should be based on the book's information and ensure that no two books have the same identifier.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Generate Unique Book Codes"

medium

WHY DOES IT MATTER?

Hash‑based deduplication is essential because it transforms a potentially quadratic comparison problem into constant‑time look‑ups, enabling systems to handle massive catalogs without performance degradation.

OPTIMIZATION CHALLENGE

The key insight is to separate the problem into a fast, fixed‑size hash for primary identification and a lightweight collision‑resolution mechanism, which together reduce both time and space from O(N^2) to O(N).

REAL-WORLD CONNECTION

Think of URL shorteners: they hash a long URL into a short code and resolve collisions by appending a counter or re‑hashing, mirroring how book codes are generated at scale.

During an interview, compute the hash first, then immediately check a hash map; if a collision occurs, increment a counter stored alongside the hash—this pattern shows you understand both hashing and practical collision handling.

COMPLEXITY AT A GLANCE

⏱ Time:O(N * L)
💾 Space:O(N)

Core Theory — Why This Approach?

The problem of generating unique identifiers for books is essentially a collision‑free hashing problem. A naïve solution might concatenate the title, author, and year into a single string and use it directly as an identifier, but this approach fails when two distinct books share identical metadata (e.g., different editions with the same title and author) or when the concatenated string exceeds storage constraints. Moreover, string concatenation without a deterministic hash can lead to variable‑length identifiers, hurting indexing performance in databases. The optimal paradigm leverages a fixed‑size hash function (such as SHA‑256, MurmurHash, or a custom polynomial rolling hash) to compress the combined attributes into a compact, constant‑length code. To guarantee absolute uniqueness, a secondary collision‑resolution step—typically a deterministic counter or a secondary hash—is appended only when the primary hash collides, ensuring O(1) average‑case insertion while preserving O(N) overall time.

On large inputs (hundreds of thousands to millions of books), the naïve approach becomes prohibitive because each identifier must be compared against all previously generated identifiers, leading to O(N^2) time. By using a hash table (unordered_map/dictionary) keyed by the primary hash, we achieve constant‑time look‑ups and insertions. The combination of a strong hash function and a hash table yields an overall linear time algorithm with respect to the number of books, while the space usage remains linear, storing only the hash and optional counter for each entry. This pattern—hash‑based deduplication with collision handling—is a cornerstone of many large‑scale indexing and distributed key‑generation systems.

Interview Questions on This Problem

Q1How would you design a system that generates unique book codes when two books have identical title, author, and year?

First, compute a deterministic hash of the concatenated attributes. Store the hash in a hash table. If the hash already exists, increment a per‑hash counter and append it (or re‑hash with a salt) to form a new code, guaranteeing uniqueness while keeping the identifier length bounded.

Q2What are the trade‑offs between using a cryptographic hash (e.g., SHA‑256) versus a non‑cryptographic hash (e.g., MurmurHash) for this problem?

Cryptographic hashes provide negligible collision probability even without a secondary check, but they are slower and consume more CPU. Non‑cryptographic hashes are faster and sufficient when a secondary collision‑resolution step is in place, making them preferable for high‑throughput systems where performance matters more than adversarial resistance.

Q3Explain how you would scale the unique code generation to a distributed environment with multiple writer nodes.

Assign each writer a unique namespace prefix (e.g., node ID) and combine it with the local hash. Alternatively, use a consistent‑hash ring to route each book's metadata to a single shard responsible for generating the code, ensuring that collisions are resolved locally and the global identifier remains unique.

Examples

Example 1

Input

[['Book1', 'Author1', 2020], ['Book2', 'Author2', 2021]]

Output

["Book1_Author1_2020","Book2_Author2_2021"]

Explanation: Step 1: Create a list of unique identifiers by combining the title, author, and publication year of each book. For the first book, we combine 'Book1', 'Author1', and '2020' to get 'Book1_Author1_2020'. For the second book, we combine 'Book2', 'Author2', and '2021' to get 'Book2_Author2_2021'.

Example 2

Input

[['Book3', 'Author3', 2022], ['Book3', 'Author3', 2022]]

Output

["Book3_Author3_2022","Book3_Author3_2022"]

Explanation: Step 1: Create a list of unique identifiers by combining the title, author, and publication year of each book. For the first book, we combine 'Book3', 'Author3', and '2022' to get 'Book3_Author3_2022'. For the second book, we combine 'Book3', 'Author3', and '2022' to get 'Book3_Author3_2022'. Note that the output is not unique, as the function does not handle the case when two books have the same title, author, and publication year.

Constraints

  • 1 <= number of books <= 1000
  • 1 <= length of title <= 50
  • 1 <= length of author <= 50
  • 1900 <= publication year <= 2100

Optimal Approach & Strategy

Hash the combined attributes into a fixed‑size value, store it in a hash table, and resolve any collisions with a deterministic counter or secondary hash.

Brute Force Approach

Generate a raw concatenated string for each book and compare it against every previously generated identifier to ensure uniqueness.

Verified Code Solutions

JavaScript Solution
Time: O(N * L)
function generateUniqueBookCodes(books) {
   let uniqueCodes = [];
   for (let book of books) {
       let code = book[0] + '_' + book[1] + '_' + book[2];
       if (!uniqueCodes.includes(code)) {
           uniqueCodes.push(code);
       }
   }
   return uniqueCodes;
}

Asked in Top Tech Interviews

uncategorizedmediumnone

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.