Skip to content

Commit 448f035

Browse files
committed
Updated the ransom note program with solution and explaination
1 parent dd7a2d5 commit 448f035

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Problem Title
2+
3+
**Difficulty:** Easy
4+
**Category:** Strings,Hash table
5+
**Leetcode Link:** [Problem Link]https://leetcode.com/problems/ransom-note/
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
You are given two strings: ransomNote and magazine.
12+
You need to determine if you can construct the ransomNote using the letters from magazine.
13+
14+
Each letter in magazine can only be used once in ransomNote.
15+
Return true if possible, otherwise return false.
16+
17+
Constraints:
18+
19+
1 <= ransomNote.length, magazine.length <= 10⁵
20+
21+
ransomNote and magazine consist of lowercase English letters
22+
23+
---
24+
25+
## 💡 Approach & Key Insights
26+
27+
The key idea is to count the frequency of each character in both ransomNote and magazine.
28+
Then, ensure that for each character required by the ransom note, the magazine has at least that many occurrences.
29+
30+
A brute force approach would be inefficient.
31+
Instead, we can use a hash map (or Python’s collections.Counter) to store and compare character frequencies efficiently.
32+
33+
---
34+
35+
## 🛠️ Breakdown of Approaches
36+
37+
### 1️⃣ Brute Force / Naive Approach
38+
39+
-**Explanation:** For every character in ransomNote, loop through magazine and find a match, removing used characters.
40+
This leads to nested iterations and repeated string operations.
41+
42+
- **Time Complexity:** *O(n^2) - nested loops for character comparisons*
43+
- **Space Complexity:** *O(1) - no additional data structures used*
44+
- **Example/Dry Run:**
45+
46+
Example input: ransomNote = "aa", magazine = "aab"
47+
Step 1 → Check for 'a' in magazine → Found
48+
Step 2 → Remove 'a' → magazine = "ab"
49+
Step 3 → Check for 'a' again → Found
50+
Step 4 → Return true
51+
52+
53+
### 2️⃣ Optimized Approach
54+
55+
- **Explanation:** Use a hash map to count how many times each letter appears in magazine.
56+
Then, for each letter in ransomNote, check if it exists in the map with sufficient count. Decrease the count as we go
57+
58+
- **Time Complexity:** *O(m + n) - where m = len(magazine), n = len(ransomNote)*
59+
- **Space Complexity:** *O(1)-because character set is fixed (26 lowercase letters)
60+
61+
- **Example/Dry Run:**
62+
63+
ransomNote = "aa", magazine = "aab"
64+
Step 1 → magazine_counter = {'a': 2, 'b': 1}
65+
Step 2 → Check 'a' in ransomNote → Yes (2 available) → decrement to 1
66+
Step 3 → Check 'a' again → Yes (1 available) → decrement to 0
67+
Step 4 → Return true
68+
69+
70+
### 3️⃣ Best / Final Optimized Approach (if applicable)
71+
72+
- **Explanation:** * Use a hash map to count how many times each letter appears in magazine.
73+
Then, for each letter in ransomNote, check if it exists in the map with sufficient count. Decrease the count as we go*
74+
- **Time Complexity:** *O(m + n) - where m = len(magazine), n = len(ransomNote)*
75+
- **Space Complexity:** *O(1) - because character set is fixed (26 lowercase letters)*
76+
- **Example/Dry Run:**
77+
78+
Example input:
79+
ransomNote = "aa", magazine = "aab"
80+
Step 1 → magazine_counter = {'a': 2, 'b': 1}
81+
Step 2 → Check 'a' in ransomNote → Yes (2 available) → decrement to 1
82+
Step 3 → Check 'a' again → Yes (1 available) → decrement to 0
83+
Step 4 → Return true
84+
---
85+
86+
## 📊 Complexity Analysis
87+
88+
| Approach | Time Complexity | Space Complexity |
89+
| ------------- | --------------- | ---------------- |
90+
| Brute Force | O(n^2) | O(1) |
91+
| Optimized | O(m + n) | O(1) |
92+
| Best Approach | O(m + n) | O(1) |
93+
94+
---
95+
96+
## 📉 Optimization Ideas
97+
98+
Use collections.Counter in Python for cleaner syntax and built-in methods for frequency counting and subtraction.
99+
100+
Early exit: if len(ransomNote) > len(magazine), return False immediately.
101+
102+
---
103+
104+
## 📌 Example Walkthroughs & Dry Runs
105+
106+
Example:
107+
Input: ransomNote = "abc", magazine = "aabbcc"
108+
Process:
109+
1 → Count magazine: {'a': 2, 'b': 2, 'c': 2}
110+
2 → 'a' needed → OK
111+
3 → 'b' needed → OK
112+
4 → 'c' needed → OK
113+
Output: true
114+
115+
Input: ransomNote = "aab", magazine = "abc"
116+
Process:
117+
1 → Count magazine: {'a': 1, 'b': 1, 'c': 1}
118+
2 → 'a' needed → Only 1 'a' available
119+
Output: false
120+
121+
---
122+
123+
## 🔗 Additional Resources
124+
125+
- collections.Counter docs
126+
- Pythonic Solution Discussion
127+
128+
129+
---
130+
131+
Author: Andrew
132+
Date: 13/06/2025
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution(object):
2+
def canConstruct(self, ransomNote, magazine):
3+
ransom_count = Counter(ransomNote)
4+
magazine_count = Counter(magazine)
5+
6+
for letter, count in ransom_count.items():
7+
if magazine_count[letter] < count:
8+
return False
9+
10+
return True

LeetCode-Solutions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit dd7a2d5de50b2544eb285506601392340c529811

0 commit comments

Comments
 (0)