questions D-E

This commit is contained in:
2025-05-25 11:08:40 +01:00
parent 615e3f1291
commit 360b5fa255
18 changed files with 4022 additions and 0 deletions

View File

@@ -0,0 +1,190 @@
title: Excel Sheet Column Title
slug: excel-sheet-column-title
difficulty: easy
leetcode_id: 168
leetcode_url: https://leetcode.com/problems/excel-sheet-column-title/
categories:
- strings
- math
patterns:
- greedy
function_signature: "def convert_to_title(column_number: int) -> str:"
test_cases:
visible:
- input: { column_number: 1 }
expected: "A"
- input: { column_number: 28 }
expected: "AB"
- input: { column_number: 701 }
expected: "ZY"
hidden:
- input: { column_number: 26 }
expected: "Z"
- input: { column_number: 27 }
expected: "AA"
- input: { column_number: 52 }
expected: "AZ"
description: |
Given an integer `columnNumber`, return *its corresponding column title as it appears in an Excel sheet*.
For example:
```
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...
```
constraints: |
- `1 <= columnNumber <= 2^31 - 1`
examples:
- input: "columnNumber = 1"
output: '"A"'
explanation: "The 1st column in Excel is labeled 'A'."
- input: "columnNumber = 28"
output: '"AB"'
explanation: "After Z (26), we wrap to AA (27), then AB (28)."
- input: "columnNumber = 701"
output: '"ZY"'
explanation: "701 = 26 * 26 + 25 = 676 + 25. The first character is Z (26th letter), and the second is Y (25th letter)."
explanation:
intuition: |
This problem is essentially converting a number to **base-26**, but with an important twist: Excel columns are **1-indexed**, not 0-indexed.
In standard base-26 (like hexadecimal is base-16), the digits would be 0-25. But Excel uses A-Z representing 1-26. There's no "zero" character!
Think of it like this: imagine you're reading an odometer, but instead of digits 0-9, you have letters A-Z. And unlike a normal odometer where 0 exists, this one starts at A (which represents 1).
The key insight is that before extracting each "digit", we need to **subtract 1** to shift from 1-indexed to 0-indexed. This converts our 1-26 range to 0-25, which maps perfectly to A-Z using modulo arithmetic.
For example, with `columnNumber = 28`:
- Subtract 1 → 27
- 27 % 26 = 1 → maps to 'B'
- 27 // 26 = 1
- Subtract 1 → 0
- 0 % 26 = 0 → maps to 'A'
- Result: "AB" (reversed from our extraction order)
approach: |
We solve this using **repeated division with 1-index adjustment**:
**Step 1: Initialise result string**
- `result`: Empty string to build our column title
&nbsp;
**Step 2: Extract characters from right to left**
- While `columnNumber > 0`:
- **Subtract 1** from `columnNumber` to convert from 1-indexed to 0-indexed
- Get the remainder when divided by 26 — this gives us the current character (0 = A, 1 = B, ..., 25 = Z)
- Convert the remainder to a character using `chr(remainder + ord('A'))`
- **Prepend** this character to the result (or append and reverse at the end)
- Divide `columnNumber` by 26 to move to the next position
&nbsp;
**Step 3: Return the result**
- Return the constructed column title string
&nbsp;
The subtraction step is crucial — it handles the fact that there's no "zero" in Excel's numbering. Without it, 'Z' (26) would incorrectly produce 'AZ' instead of just 'Z'.
common_pitfalls:
- title: Forgetting the 1-Index Adjustment
description: |
The most common mistake is treating this as standard base-26 conversion without accounting for 1-indexing.
For example, without subtracting 1:
- `columnNumber = 26` → 26 % 26 = 0, 26 // 26 = 1 → gives "A" + something
- But the answer should be just "Z"!
The subtraction converts our 1-26 range to 0-25, making the modulo operation work correctly.
wrong_approach: "Direct modulo without adjustment"
correct_approach: "Subtract 1 before each modulo operation"
- title: Building String in Wrong Order
description: |
When extracting digits via repeated division, we get them in reverse order (rightmost first). A common error is appending characters and forgetting to reverse, or getting confused about which end to add to.
For `28`:
- First extraction gives 'B' (the rightmost character)
- Second extraction gives 'A' (the leftmost character)
- If we append: "BA" (wrong!)
- If we prepend: "AB" (correct!)
wrong_approach: "Appending characters without reversing"
correct_approach: "Prepend each character, or append then reverse at the end"
- title: Off-By-One with Character Mapping
description: |
After the modulo operation, the remainder is 0-25. Some implementations incorrectly use `chr(remainder + ord('A') + 1)` or similar, resulting in off-by-one errors.
Remember: remainder 0 should map to 'A', remainder 1 to 'B', etc. Since `ord('A')` is 65, we use `chr(remainder + 65)` or `chr(remainder + ord('A'))`.
key_takeaways:
- "**1-indexed systems require adjustment**: When a numbering system starts at 1 instead of 0, subtract 1 before modulo operations"
- "**Base conversion pattern**: This technique of repeated division and modulo extends to any base conversion (binary, hex, etc.)"
- "**Build strings carefully**: When extracting digits right-to-left, remember to reverse or prepend"
- "**Related problems**: Excel Sheet Column Number (LC 171) is the inverse operation — converting title back to number"
time_complexity: "O(log<sub>26</sub> n). Each iteration divides the number by 26, so we perform approximately log base 26 of n iterations."
space_complexity: "O(log<sub>26</sub> n). The output string length is proportional to the number of iterations."
solutions:
- approach_name: Iterative Division
is_optimal: true
code: |
def convert_to_title(column_number: int) -> str:
result = []
while column_number > 0:
# Subtract 1 to convert from 1-indexed to 0-indexed
column_number -= 1
# Get the current character (0 = A, 1 = B, ..., 25 = Z)
remainder = column_number % 26
result.append(chr(remainder + ord('A')))
# Move to the next position
column_number //= 26
# We built the string right-to-left, so reverse it
return ''.join(reversed(result))
explanation: |
**Time Complexity:** O(log<sub>26</sub> n) — We divide by 26 each iteration.
**Space Complexity:** O(log<sub>26</sub> n) — The result list stores one character per iteration.
The key insight is subtracting 1 before each modulo operation. This converts from Excel's 1-indexed system (A=1, Z=26) to a 0-indexed system (A=0, Z=25) that works naturally with modulo arithmetic.
- approach_name: Recursive Solution
is_optimal: false
code: |
def convert_to_title(column_number: int) -> str:
if column_number == 0:
return ""
# Subtract 1 for 1-indexed adjustment
column_number -= 1
# Recursively get the prefix, then append current character
return convert_to_title(column_number // 26) + chr(column_number % 26 + ord('A'))
explanation: |
**Time Complexity:** O(log<sub>26</sub> n) — Same number of operations as iterative.
**Space Complexity:** O(log<sub>26</sub> n) — Call stack depth plus result string.
This recursive approach builds the string naturally in the correct order by recursing first (handling higher-order digits) then appending the current character. While elegant, it uses additional stack space compared to the iterative solution.